Хранение значений массива в одной переменной - PullRequest
1 голос
/ 02 июня 2010

Я пытаюсь использовать код 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;
}

Ответы [ 8 ]

4 голосов
/ 02 июня 2010

Объявление массива и 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
}
1 голос
/ 02 июня 2010

Поскольку вы хотите дублировать, хранить, сравнивать, освобождать и, возможно, дайджест 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 ).

P.S. : мой код C здесь для того, чтобы «проиллюстрировать» мою точку зрения, а не для того, чтобы ее можно было использовать, просто скопировав / вставив ее как есть ...

1 голос
/ 02 июня 2010

Просто передайте буфер и его размер этой функции:

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]);
        }
    }
}
1 голос
/ 02 июня 2010

Вы можете определить переменную:

char **md5sums;

Затем вам нужно будет изменить MDPrint, чтобы вместо этого возвращать неправильную строку с нулем в конце с 32 шестнадцатеричными цифрами. Вы можете в основном повторно использовать существующий цикл, но вместо этого используйте sprintf.

Затем добавьте main добавить каждую md5sum (символ *) к 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?

РЕДАКТИРОВАТЬ: я исправил некоторые неправильные счета.

0 голосов
/ 02 июня 2010

Вы знаете, где хранится сумма, по тому, как вы ее печатаете: через -> дайджест [i]. Который определяется как

unsigned char digest[16];

Таким образом, вам просто нужно скопировать эти 16 беззнаковых символов в другой массив беззнаковых символов (не менее 16 без знака). Функция memcpy может сделать это. Если вам нужно сравнить две суммы, вы можете использовать memcmp (размер сравнения будет 16*sizeof(unsigned char), что равно 16, а sizeof (unsigned char) 1.

0 голосов
/ 02 июня 2010

Почему бы не сделать функцию

MD5File (char * имя файла, unsigned char * digest) {

/ * как и раньше * / memcpy (digest, mdContext-> digest, 16); возвращение;

}

чтобы за пределами функции у вас был доступ к дайджесту (после его печати)?

Дайджест - это просто массив из 16 беззнаковых символов ...

0 голосов
/ 02 июня 2010

Просто оставь в массиве! Вы не храните его в переменной; потому что это уже в переменной .. Просто создайте глобальную переменную, сохраните в ней хеш 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;
}
0 голосов
/ 02 июня 2010

Сохраните его как строку, а затем используйте strcmp () для сравнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...