Проблемы в дайджесте сообщения второго блока в самообучающемся алгоритме SHA-1

Выход

Я новичок в изучении программирования на C. Теперь я пытаюсь сделать SHA-1 для университетского проекта. Я думаю, что это кодирование самостоятельно. Я пытаюсь сделать дайджест сообщения из файла выше 55 символов, что означает, что необходимо 2 блока. Дайджест сообщения первого блока правильный, но второй блок неверный. Я проверял это очень много раз, но так и не смог найти ошибку. Может ли кто-нибудь с опытом, способным помочь мне узнать это? Спасибо.

информация о пациентах.txt "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"

      #include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  int length,number_of_block,str_length;
  unsigned int i = 0,j = 0,l = 0,e = 0,n = 0, t=0, k=0,f=0;
  float x=0;
  char c;
  int H[5]={0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0};
  unsigned int temp = 0;

  FILE *file;
  file = fopen("patients information.txt", "r");//Choose the file that want to access
  if (file == NULL)//detect the file is empty or not
  {
      printf("The file is empty");
  }

  fseek(file, 0, SEEK_END);// move the file pointer to the end of the file
  length = ftell(file);//calculate the length of sting in file
  fseek(file, 0, SEEK_SET);// move file pointer back to start of file so we can read each character

  printf("The length of string is %d\n",length);//check the number of character in string

  char *string = malloc(sizeof(char) * (length+1));

  while ( (c = fgetc(file)) != EOF)//pass the every character in the file to the string array
  {
    string[i] = c;
    i++;
  }

  string[i] = '\0';//terminate the string storing

  unsigned char long_msg[length+1];

  for (i=0;i<length;i++)//pass the pointer array to the unsigned character array
  {
      long_msg[i]=string[i];
  }

  printf("The character store in th array is ");

  long_msg[length]=128;

  for (i=0;i<=length;i++)//check the message in msg array
  {
      printf("%X ",long_msg[i]);
  }

  if (length<=55)
  {
      number_of_block = 1;
  }
  else if (length>55 && length<120)
  {
      number_of_block = 2;
  }
  else
  {
      x = ((length - 55)/64);//calculate the number of block needed
      number_of_block = x+2;
  }

  printf("\nNumber of block needed is %d\n",number_of_block);

  unsigned char blocks[number_of_block][64];

  for (i=0;i<number_of_block;i++)//Split the long string into n number of blocks
  {
      for(j=0;j<64;j++)
      {
          blocks[i][j]=long_msg[l];
          if(l>length)//padding 0
          {
              blocks[i][j]=0;
          }
          l++;
      }
  }
  for (i=0;i<number_of_block;i++)//check the blocks content

  {
      for(j=0;j<64;j++)
      {
          printf("%X ",blocks[i][j]);
      }
  }
  printf("\nCheck length padding:\n");
  str_length = 8*length;//sting length in bits

  if (length<32)//if length of string is 1 bytes in hexadecimal
  {
      blocks[number_of_block-1][63]=str_length;
  }
  else
  {
      blocks[number_of_block-1][62]=(str_length>>8);//second last block
      blocks[number_of_block-1][63]=((str_length<<8)>>8);//last block
  }

   for (i=0;i<number_of_block;i++)//check length padding
  {
      for(j=0;j<64;j++)
      {
          printf("%02X ",blocks[i][j]);
      }
  }

  unsigned int w[number_of_block][16][4];
  unsigned int W[number_of_block][80];
  unsigned int A[number_of_block],B[number_of_block],C[number_of_block],D[number_of_block],E[number_of_block];


  for (e=0;e<number_of_block;e++)
  {
      /*The problem is here*/
      n=0;
      for (i=0;i<16;i++)//split the padding message into w0 to w15 ,exp. w0 = (w[0][1]),....,(w[0][3])
        {
            for(j=0;j<4;j++)
            {
                w[e][i][j] = blocks[e][n];
                n++;
            }
        }

      for (i=0;i<16;i++)//combine the hex --> 16 block of hexadecimal(W0 to W15)
        {
            W[e][i] = ((w[e][i][0])<<24 | (w[e][i][1])<<16 | (w[e][i][2])<<8 | (w[e][i][3]));
        }

    /*Compute message digest*/
        A[e] = 0x67452301;
        B[e] = 0xEFCDAB89;
        C[e] = 0x98BADCFE;
        D[e] = 0x10325476;
        E[e] = 0xC3D2E1F0;


      for (t=0;t<=79;t++)
    {
        //for t = 16 -> 79
        if (t>=16 && t<=79)//prepare W16 to W79
        {
            W[e][t]= ( (W[e][t-3]) ^ (W[e][t-8]) ^ (W[e][t-14]) ^ (W[e][t-16]) );
            W[e][t]= ( ((W[e][t])<<1) | ((W[e][t]) >> (32-1)));//perform circular left shift
        }

        if (t>=0 && t<=19)
        {
            f = (B[e]&C[e]) | ((~B[e])&D[e]);
            k = 0x5A827999;
        }
        else if (t>=20 && t<=39)
        {
            f = (B[e]^C[e]^D[e]);
            k = 0x6ED9EBA1;
        }
        else if (t>=40 && t<=59)
        {
            f = (B[e]&C[e]) | (B[e]&D[e]) | (C[e]&D[e]);
            k = 0x8F1BBCDC;
        }
        else if(t>=60 && t<=79)
        {
            f = (B[e]^C[e]^D[e]);
            k = 0xCA62C1D6;
        }

        temp = ((A[e]<<5) | (A[e] >> (32-5))) + f + E[e] + W[e][t] + k;

        E[e] = D[e];
        D[e] = C[e];
        C[e] = ( (B[e]<<30) | (B[e]>> (32-30)));
        B[e] = A[e];
        A[e] = temp;
    }
    printf("\n\n");

    printf("%08X %08X %08X %08X %08X",A[e],B[e],C[e],D[e],E[e]);//check the value before adding up

    H[0] = ( H[0] + A[e]);
    H[1] = ( H[1] + B[e]);
    H[2] = ( H[2] + C[e]);
    H[3] = ( H[3] + D[e]);
    H[4] = ( H[4] + E[e]);
  }
  printf("\n\n");

  printf("Message digest:");
  for (i=0;i<5;i++)
    {
       printf("%X ",H[i]);
    }

    printf("\n\n");

  return 0;
}


Неверный вывод второго блока: CE3A1FD0 01464A63 F6766B50 AF97AC62 8D5DBBDD Выход второго блока должен быть: 906FD62C 58C0AAC0 B6A55520 74E9B89D 9AF00B7F

0 ответов

Другие вопросы по тегам