2013-06-24 35 views
1

我遇到了一个算法,我正在做的解密数据的问题。 这是我每次尝试运行发生溢出错误时遇到的问题:xxtea溢出变量总和在c#

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(); 

     } 


    } 

回答

0

如果我读取你的代码的权利......该行将始终溢出,因为numberOfRounds大于1. uint在C#中只是uint32的别名,因为Delta这么大(最重要的位是1),当你将Delta乘以任何东西时,计算总是会溢出。但是,如果我正确读取你的代码,那么计算应该是一个加法,而不是当前的乘法,如果这不正确,我建议将sum更改为uint64