【问题标题】:Storing values of an array in one variable将数组的值存储在一个变量中
【发布时间】:2010-06-02 11:41:33
【问题描述】:

我正在尝试使用 md5 代码来计算文件的校验和。现在给定的函数在屏幕上打印出(先前计算的)校验和,但我想将它存储在一个变量中,以便稍后进行比较。

我想主要问题是我想将数组的内容存储在一个变量中。 我该如何管理? 可能这是一个非常愚蠢的问题,但也许有人可以提供帮助。

下面是打印值的函数。我想修改它以将结果存储在一个变量中。

static void MDPrint (MD5_CTX* mdContext)
{
 int i;
 for (i = 0; i < 16; i++)
 {
   printf ("%02x", mdContext->digest[i]);
 } // end of for 
} // end of function

出于完整性的原因,使用的结构:

 /* typedef a 32 bit type */
 typedef unsigned long int UINT4;

 /* Data structure for MD5 (Message Digest) computation */
 typedef struct {
  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
  UINT4 buf[4];                                    /* scratch buffer */
  unsigned char in[64];                              /* input buffer */
  unsigned char digest[16];     /* actual digest after MD5Final call */
 } MD5_CTX;

以及用于计算校验和的函数:

static int MDFile (char* filename)
{
 FILE *inFile = fopen (filename, "rb");
 MD5_CTX mdContext;
 int bytes;
 unsigned char data[1024];

 if (inFile == NULL) {
    printf ("%s can't be opened.\n", filename);
    return -1;
 } // end of if
 MD5Init (&mdContext);
 while ((bytes = fread (data, 1, 1024, inFile)) != 0)
 MD5Update (&mdContext, data, bytes);
 MD5Final (&mdContext);
 MDPrint (&mdContext);
 printf (" %s\n", filename);
 fclose (inFile);
 return 0;
}

【问题讨论】:

    标签: c arrays variables md5


    【解决方案1】:

    声明一个数组并memcpy结果。

    例子:

    unsigned char old_md5_dig[16]; // <-- binary format
    ...
    
    MD5_CTX mdContext;
    MD5Init(&mdContext);
    MD5Update(&mdContext, data, bytes);
    MD5Final(&mdContext);
    memcpy(old_md5_dig, mdContext.digest, 16); // <--
    

    编辑:要将以前的与新的 md5 哈希值进行比较,您可以使用 memcmp

    if (memcmp(old_md5_dig, mdContext.digest, 16)) {
       // different hashes
    }
    

    【讨论】:

    • 这很简单,正确且正是 OP 所需要的。我只想补充一点,您稍后会使用memcmp() 来比较这些数组。
    【解决方案2】:

    只需将 char 缓冲区及其大小传递给此函数:

    static void MDGen (mdContext, buf, size)
    MD5_CTX *mdContext;
    char *buf;
    size_t size;
    {
        int i;
        int minSize = 33; // 16 pairs of hex digits plus terminator
    
        if ((buf != NULL) && (size >= minSize))
        {
            memset(buf, 0, size);
    
            for (i = 0; i < 16; i++)
            {
                snprintf(buf + (i*2), size - (i*2), "%02x", mdContext->digest[i]);
            }
        }
    }
    

    【讨论】:

    • 我会试试这个,在这里我想我知道我的 s(n)printf 函数有什么问题了。
    【解决方案3】:

    你可以定义一个变量:

    char **md5sums;
    

    然后您将需要修改 MDPrint 以返回一个包含 32 个十六进制数字的 malloced 以 null 结尾的字符串。您基本上可以重用现有的循环,但使用 sprintf 代替。

    然后让 main 将每个 md5sum(一个 char*)添加到 md5sums。您将需要使用 realloc 为 md5sums 分配内存,因为您不知道前面的元素数量。

    应该是:

    static char* MDString (mdContext) 
    MD5_CTX *mdContext; 
    { 
      int i; 
      char *digest = malloc(sizeof(char) * 33);
      if(digest == NULL)
      { 
        return NULL;
      }
      for (i = 0; i < 16; i++)
      { 
        sprintf(digest + (i * 2), "%02x", mdContext->digest[i]); 
      } 
      return digest;
    }
    

    此外,您应该通过编辑问题来修改代码。为什么要使用 K&R 语法?

    编辑:我修正了一些不正确的计数。

    【讨论】:

    • 感谢您迄今为止的所有 cmets。我尝试了您之前提出的方式,但我没有设法在现有循环中使用具有正确参数的 sprintf 。我的尝试看起来像: 以前启动: char test[]="d41d8cd98f00b204e9800998ecf8427e";在循环中: sprintf(test[i],"%02x",mdContext->digest[i]);这导致“传递'sprintf'的参数1使指针从整数而不进行强制转换”
    【解决方案4】:

    由于您想复制、存储、比较、免费甚至更多 MD5 摘要,只需创建一个md5_t 类型并编写适当的函数来操作它,即:

    typedef char md5_t[16];
    
    md5_t *md5_new( MD5_CTX *pMD5Context )
    {
         md5_t *pMD5 = malloc( sizeof( md5_t ) );
         memcpy( pMD5, pMD5Context->digest, 16 );
         return pMD5 ;
    }
    
    int md5_cmp( md5_t *pMD5A, md5_t *pMD5B )
    {
         return memcmp( pMD5A, pMD5B, 16 );
    }
    
    void md5_print( md5_t *pMD5 )
    {
         ...
    }
    
    
    void md5_free( md5_t *pMD5 )
    {
         free( pMD5 );
    }
    

    等等……接下来,为你的 MD5 数组创建一个类型和简单的函数来操作它:

     typedef struct md5array_t { 
         unsigned int  uSize ;
         md5_t       **ppMD5 ;
     }
    
     md5array_t *md5array_new()
     {
         md5array_t *pArray = malloc( sizeof( md5array_t );
         pArray->uSize = 0 ;
         pArray->ppMD5 = NULL ;
     }
    
     md5array_t *md5array_add( md5array_t *pArray, md5_t *pMD5 )
     {
         pArray->uSize ++ ;
         pArray = realloc( pArray, pArray->uSize + sizeof( md5_t * ) );
         pArray->ppMD5[ pArray->uSize-1 ] = pMD5 ;
     }
    
     md5_t *md5array_get( md5array_t *pArray, unsigned int uIndex )
     {
         return pArray->ppMD5[ uIndex ];
     }
    
     void md5array_free( md5array_t *pArray }
     {
          /* I let you find what to write here.
          Be sure to read AND understand the previous
          functions. */
     }
    

    恢复:创建一个类型和你需要操作它的函数,只要你想对一个数据进行多个操作。您不需要创建一个真正的泛型类型,其中包含代表您可以想象的对该类型的尽可能多的操作的完整函数:只需编写您需要的代码。比如在md5array_t中,可以加一个md5_t *但是不能删除(除非你写了函数void md5array_del( md5array_t *pArray *, int iIndex )

    附: :我的 C 代码在这里“说明”我的观点,而不是通过按原样复制/粘贴来使用...

    【讨论】:

    • md5_t是数组类型,不能有函数返回数组,所以md5_new()的定义是错误的。
    • @caf 你是对的,这是一个拼写错误,现在更正了。谢谢。
    【解决方案5】:

    将其存储为字符串,然后使用 strcmp() 进行比较。

    【讨论】:

    • strcmp 仅适用于以空字符结尾的字符串。在这里使用 memcmp。
    【解决方案6】:

    只留下一个数组! 您没有将其存储在变量中;因为它已经在变量中了.. 只需创建全局变量,在其中存储 MD5 哈希值,然后进行比较。

    你需要的是 MD5IsEqual 函数,它需要 2 个这样的数组。

    int MD5IsEqual(unsigned char *x, unsigned char* y)
    {
       int i;
       for(i=0; i<16;i++)
          if(x[i] != y[i]) 
              return 0;
       return 1;
    }
    

    【讨论】:

      【解决方案7】:

      为什么不做函数

      MD5File(char * 文件名, unsigned char *digest){

      /* 和以前一样 */ memcpy(摘要,mdContext->摘要,16); 返回;

      }

      这样您就可以在函数之外访问摘要(在打印之后)?

      摘要只是一个包含 16 个无符号字符的数组...

      【讨论】:

        【解决方案8】:

        您通过打印的方式知道总和的存储位置:通过 ->digest[i]。定义如下

        unsigned char digest[16];

        所以您基本上只需将这 16 个 unsigned char 复制到另一个 unsigned char 数组中(至少 16 个 unsigned char 长)。函数 memcpy 可以做到这一点。如果需要比较两个和,可以使用memcmp(比较大小为16*sizeof(unsigned char),即16,即sizeof(unsigned char) 1。

        【讨论】:

          猜你喜欢
          • 2022-01-22
          • 2012-07-10
          • 2023-03-23
          • 1970-01-01
          • 2022-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多