1

我在解密数据时遇到了算法问题。每次我尝试运行溢出错误时都会出现问题:

uint sum=(numberOfRounds*Delta);

我正在读取的文件只有十六进制数组: 3D 00 01 12 02 CC F8 FD 33 3B 44 01 00 92 00 03 03 00 CB 44 6D 38 01 12 00 24 D6 23 02 04 E9 65 F7 44 00 00 00 00 00 5B D2 D6 ED 3A 81 03 DD 00 00 00 00 00 00 AC 87 B0 51 0F 27 01 00 D9

代码如下:

 private const int EncryptedDataBlockSizeInBytes = 4;

  private static readonly uint[] Key = new uint[] { 0xA50DADD1, 0xFEAD1276, 0x03948029, 0x49493095 };
  private const uint Delta = 0x9E3779B9;

  public static int headersize = 13;
  public static int crcsize = 1;


  public static byte[] Decrypt(byte[] data, int offset, int count, uint[] key)
  {
   if (count % EncryptedDataBlockSizeInBytes != 0)
   {
    throw new ArgumentException("The count of the data to be decrypted must be divisible by 4.");
   }

   // Convert the byte array into a uint array
   uint[] dataInUints = ConvertBytesToUints(data, offset, count);

   uint numberOfRounds = (uint)(6 + (52 / dataInUints.Length));
   uint n = (uint)(dataInUints.Length - 1);
   uint sum = numberOfRounds * Delta;
   uint y = dataInUints[0];

   do
   {
        uint e = (sum >> 2) & 3;

        uint z;
        for (uint i = n; i > 0; i--)
        {
         z = dataInUints[i - 1];
         dataInUints[i] -= XxteaMx(z, y, e, sum, key, i);
         y = dataInUints[i];
        }

        z = dataInUints[n];
        dataInUints[0] -= XxteaMx(z, y, e, sum, key, 0);
        y = dataInUints[0];

        sum -= Delta;
   }
   while (sum != 0);

   // Convert the decrypted data back into a byte array and return the result
   return ConvertUintsToBytes(dataInUints);
  }




  private static uint XxteaMx(uint z, uint y, uint e, uint sum, uint[] key, uint i)
  {
   return (((((z) >> 5) ^ ((y) << 2)) + (((y) >> 3) ^ ((z) << 4))) ^ (((sum) ^ y) + ((key)[((i) & 3U) ^ (e)] ^ (z))));
  }



  private static uint[] ConvertBytesToUints(byte[] data, int offset, int count)
  {
   uint[] result = new uint[count / 4];

   // Run through the data and create the uints from
   // the array of bytes
   for (int i = offset, j = 0; i < offset + count; i += 4, j++)
   {
    result[j] = ((uint)data[i + 3] << 24) | ((uint)data[i + 2] << 16) | ((uint)data[i + 1] << 8) | (data[i]);
   }

   // Return the array of uints
   return result;
  }


  private static byte[] ConvertUintsToBytes(uint[] data)
  {
   byte[] result = new byte[data.Length * 4];

   // Run through the data and create the bytes from
   // the array of uints
   for (int i = 0, j = 0; i < data.Length; i++, j += 4)
   {
    result[j] = (byte)(data[i]);
    result[j + 1] = (byte)(data[i] >> 8);
    result[j + 2] = (byte)(data[i] >> 16);
    result[j + 3] = (byte)(data[i] >> 24);
   }

   // Return the array of bytes
   return result;
  }




        void Button1Click(object sender, EventArgs e)
        {


                FileStream file = new FileStream("arquivobin.dat", FileMode.Open);
                BinaryReader br = new BinaryReader(file);

                byte[] data = new byte[br.BaseStream.Length];

                data = br.ReadBytes((int)br.BaseStream.Length);

                string s = "";
                richTextBox1.Text = "My binary file data:" + "\n";
                for(int i =0; i< data.Length; i++){
                    s = data[i].ToString();
                    richTextBox1.Text += s + " ";
                }

                richTextBox1.Text += "\n\n\n" ;

                richTextBox1.Text += "My HEADER:" + "\n";
                for (int i = 0; i < headersize; i++)
                {
                    s = data[i].ToString();
                    richTextBox1.Text += s + " ";
                }

                richTextBox1.Text += "\n\n\n";  

                richTextBox1.Text += "My payload:" + "\n";
                for(int i = headersize; i < data.Length - crcsize; i++){
                    s = data[i].ToString();
                    richTextBox1.Text += s + " ";
                }

                richTextBox1.Text += "\n\n\n";
                richTextBox1.Text += "My CheckSum:" + "\n";
                s = printhex(data[data.Length - crcsize]);
                richTextBox1.Text += s;

                int offset = headersize;
                int count = data.Length - crcsize - headersize;


                byte[] result = Decrypt(data, headersize, count, Key);

                richTextBox1.Text += "\n\n\n";
                richTextBox1.Text += "My Decrypted:" + "\n";

                for (int i = headersize; i < data.Length - crcsize; i++)
                {
                    s = result[i].ToString();
                    richTextBox1.Text += s + " ";
                }
                file.Close();

        }


    }
4

1 回答 1

0

如果我正确地阅读了您的代码...该行将始终溢出,只要numberOfRounds大于 1。uint在 C# 中只是一个别名,uint32因为它Delta是如此之大(最高有效位是 1)计算将始终溢出时你乘以Delta任何东西。但是,如果我正确阅读您的代码,则计算应该是加法而不是当前的乘法,如果不正确,我建议更改为sumbe uint64

于 2013-06-24T19:34:55.163 回答