У меня есть базовая реализация CRC32 после Wikipedia Фрагмент кода: 1 образец. Я думаю, что я сделал это правильно, с модификацией использования n-разрядного регистра для остаткаPolynomial вместо использования n + 1 бит в соответствии с примером.
Результат, который я получаю, отличается от результатов реализации онлайн CRC32. Что мне нужно изменить здесь в моей реализации?
Пожалуйста, игнорируйте инструкции Console.Writeline для логики.
const UInt32 poly = 0x04C11DB7;
public static UInt32 GenerateCRC_32(byte[] message)
{
byte[] augmentedMsg = new byte[message.Length + 4];
message.CopyTo(augmentedMsg, 0);
UInt32 remainder = Convert.ToUInt32(augmentedMsg[0]) << 24 |
Convert.ToUInt32(augmentedMsg[1]) << 16 |
Convert.ToUInt32(augmentedMsg[2]) << 8 |
Convert.ToUInt32(augmentedMsg[3]);
for (Int32 i = 4; i < augmentedMsg.Length; i++)
{
for (int bit = 0; bit < 8; bit++)
{
UInt32 nextBit = ((UInt32)augmentedMsg[i] >> (7 - bit)) & 0x01;
if ((remainder & 0x80000000) > 0)
{
Console.WriteLine("---------------DO XOR --------------------");
Console.WriteLine(Convert.ToString(((remainder << 1) | nextBit), 2).PadLeft(32, '0'));
Console.WriteLine(Convert.ToString(poly, 2).PadLeft(32, '0'));
Console.WriteLine("------------------------------------------");
remainder = ((remainder << 1) | nextBit) ^ poly;
Console.WriteLine(Convert.ToString(remainder, 2).PadLeft(32, '0'));
Console.WriteLine("------------------------------------------");
}
else
{
remainder = (remainder << 1) | nextBit;
Console.WriteLine("--------------NO---------------------");
Console.WriteLine(Convert.ToString(remainder, 2).PadLeft(32, '0'));
Console.WriteLine("------------------------------------------");
}
}
}
Console.WriteLine(Convert.ToString(remainder, 2).PadLeft(32, '0'));
Console.WriteLine(remainder.ToString("X"));
return remainder;
}
Я не ищу лучший способ оптимизировать логику, так как я просто пытаюсь использовать образец Википедии, используя С#.
Вводное сообщение: 'A' (hex: 0x41) Выход: 0x30476DC0 По этот сайт: Выход должен быть: 0xD3D99E8B
Я думаю, что мне не хватает разворота/инициализации CRC, но я не уверен, как изменить эту базовую реализацию, чтобы получить результат, эквивалентный результату веб-сайта.
Результат при запуске моей программы:
--------------NO---------------------
10000010000000000000000000000000
------------------------------------------
---------------DO XOR --------------------
00000100000000000000000000000000
00000100110000010001110110110111
------------------------------------------
00000000110000010001110110110111
------------------------------------------
--------------NO---------------------
00000001100000100011101101101110
------------------------------------------
--------------NO---------------------
00000011000001000111011011011100
------------------------------------------
--------------NO---------------------
00000110000010001110110110111000
------------------------------------------
--------------NO---------------------
00001100000100011101101101110000
------------------------------------------
--------------NO---------------------
00011000001000111011011011100000
------------------------------------------
--------------NO---------------------
00110000010001110110110111000000
------------------------------------------
00110000010001110110110111000000
Последняя строка в шестнадцатеричном формате: 0x30476DC0
Последующие действия в отношении @Mark Adler Комментарии: **
Я изменил приведенное выше, следующим образом: следующие изменения (комментарии добавлены в код):
- Инициализировано до 0xFFFFFFFF
- Обратный байт ввода сообщения
-
XOR до конечного значения, обратное значению XORed
public static UInt32 GenerateCRC_32 (байт [] сообщение) { byte [] augmentedMsg = новый байт [message.Length + 8]; message.CopyTo(добавленоMsg, 4);//Изменено для создания пространства для инициализации
UInt32 remainder = Convert.ToUInt32(augmentedMsg[0]) << 24 | Convert.ToUInt32(augmentedMsg[1]) << 16 | Convert.ToUInt32(augmentedMsg[2]) << 8 | Convert.ToUInt32(augmentedMsg[3]); remainder = ~remainder; // Overwrite the above and initialized the register to 0xFFFFFFFF for (Int32 i = 4; i < augmentedMsg.Length; i++) { byte reversedMessage = Reverse(augmentedMsg[i]); // Reversed the augmented message byte for (int bit = 0; bit < 8; bit++) { UInt32 nextBit = Convert.ToUInt32(reversedMessage >> (7 - bit)) & 0x1; // Use the reversed message byte if ((remainder & 0x80000000) > 0) { Console.WriteLine("---------------DO XOR --------------------"); Console.WriteLine(Convert.ToString(((remainder << 1) | nextBit), 2).PadLeft(32, '0')); Console.WriteLine(Convert.ToString(poly32, 2).PadLeft(32, '0')); Console.WriteLine("------------------------------------------"); remainder = Convert.ToUInt32((UInt32)((UInt32)(remainder << 1) | nextBit) ^ poly32); Console.WriteLine(Convert.ToString(remainder, 2).PadLeft(32, '0')); Console.WriteLine("------------------------------------------"); } else { remainder = (UInt32)((UInt32)(remainder << 1) | nextBit); Console.WriteLine("--------------NO---------------------"); Console.WriteLine(Convert.ToString(remainder, 2).PadLeft(32, '0')); Console.WriteLine("------------------------------------------"); } } } Console.WriteLine(Convert.ToString(remainder, 2).PadLeft(32, '0') + "(" + remainder.ToString("X") + ")"); remainder = (~remainder); Console.WriteLine("XOR ^ 0xFFFFFFFF : " + Convert.ToString(remainder, 2).PadLeft(32, '0') + "(" + remainder.ToString("X") + ")"); remainder = Reverse(remainder); Console.WriteLine("Reversed the Abv : " + Convert.ToString(remainder, 2).PadLeft(32, '0') + "(" + remainder.ToString("X") + ")"); return remainder;
}
Вывод:
---------------DO XOR --------------------
11111111111111111111111111111111
00000100110000010001110110110111
------------------------------------------
11111011001111101110001001001000
------------------------------------------
---------------DO XOR --------------------
11110110011111011100010010010000
00000100110000010001110110110111
------------------------------------------
11110010101111001101100100100111
------------------------------------------
---------------DO XOR --------------------
11100101011110011011001001001110
00000100110000010001110110110111
------------------------------------------
11100001101110001010111111111001
------------------------------------------
---------------DO XOR --------------------
11000011011100010101111111110010
00000100110000010001110110110111
------------------------------------------
11000111101100000100001001000101
------------------------------------------
---------------DO XOR --------------------
10001111011000001000010010001010
00000100110000010001110110110111
------------------------------------------
10001011101000011001100100111101
------------------------------------------
---------------DO XOR --------------------
00010111010000110011001001111010
00000100110000010001110110110111
------------------------------------------
00010011100000100010111111001101
------------------------------------------
--------------NO---------------------
00100111000001000101111110011011
------------------------------------------
--------------NO---------------------
01001110000010001011111100110110
------------------------------------------
--------------NO---------------------
10011100000100010111111001101100
------------------------------------------
---------------DO XOR --------------------
00111000001000101111110011011000
00000100110000010001110110110111
------------------------------------------
00111100111000111110000101101111
------------------------------------------
--------------NO---------------------
01111001110001111100001011011110
------------------------------------------
--------------NO---------------------
11110011100011111000010110111100
------------------------------------------
---------------DO XOR --------------------
11100111000111110000101101111000
00000100110000010001110110110111
------------------------------------------
11100011110111100001011011001111
------------------------------------------
---------------DO XOR --------------------
11000111101111000010110110011110
00000100110000010001110110110111
------------------------------------------
11000011011111010011000000101001
------------------------------------------
---------------DO XOR --------------------
10000110111110100110000001010010
00000100110000010001110110110111
------------------------------------------
10000010001110110111110111100101
------------------------------------------
---------------DO XOR --------------------
00000100011101101111101111001010
00000100110000010001110110110111
------------------------------------------
00000000101101111110011001111101
------------------------------------------
--------------NO---------------------
00000001011011111100110011111010
------------------------------------------
--------------NO---------------------
00000010110111111001100111110100
------------------------------------------
--------------NO---------------------
00000101101111110011001111101000
------------------------------------------
--------------NO---------------------
00001011011111100110011111010000
------------------------------------------
--------------NO---------------------
00010110111111001100111110100000
------------------------------------------
--------------NO---------------------
00101101111110011001111101000000
------------------------------------------
--------------NO---------------------
01011011111100110011111010000000
------------------------------------------
--------------NO---------------------
10110111111001100111110100000000
------------------------------------------
---------------DO XOR --------------------
01101111110011001111101000000000
00000100110000010001110110110111
------------------------------------------
01101011000011011110011110110111
------------------------------------------
--------------NO---------------------
11010110000110111100111101101110
------------------------------------------
---------------DO XOR --------------------
10101100001101111001111011011100
00000100110000010001110110110111
------------------------------------------
10101000111101101000001101101011
------------------------------------------
---------------DO XOR --------------------
01010001111011010000011011010110
00000100110000010001110110110111
------------------------------------------
01010101001011000001101101100001
------------------------------------------
--------------NO---------------------
10101010010110000011011011000010
------------------------------------------
---------------DO XOR --------------------
01010100101100000110110110000100
00000100110000010001110110110111
------------------------------------------
01010000011100010111000000110011
------------------------------------------
--------------NO---------------------
10100000111000101110000001100110
------------------------------------------
---------------DO XOR --------------------
01000001110001011100000011001100
00000100110000010001110110110111
------------------------------------------
01000101000001001101110101111011
------------------------------------------
--------------NO---------------------
10001010000010011011101011110110
------------------------------------------
---------------DO XOR --------------------
00010100000100110111010111101100
00000100110000010001110110110111
------------------------------------------
00010000110100100110100001011011
------------------------------------------
--------------NO---------------------
00100001101001001101000010110110
------------------------------------------
--------------NO---------------------
01000011010010011010000101101100
------------------------------------------
--------------NO---------------------
10000110100100110100001011011000
------------------------------------------
---------------DO XOR --------------------
00001101001001101000010110110000
00000100110000010001110110110111
------------------------------------------
00001001111001111001100000000111
------------------------------------------
--------------NO---------------------
00010011110011110011000000001110
------------------------------------------
--------------NO---------------------
00100111100111100110000000011100
------------------------------------------
00100111100111100110000000011100(279E601C)
XOR ^ 0xFFFFFFFF : 11011000011000011001111111100011(D8619FE3)
Reversed the Abv : 11000111111110011000011000011011(C7F9861B)
Это не ожидаемый результат. Я реализовал то же самое с использованием кода поиска ниже таблицы, результат точно такой же, как и выше (0xC7F9861B), что неверно
public static UInt32 GenerateCRC_32_from_Table(byte[] message)
{
byte[] augmentedMsg = new byte[message.Length + 4];
message.CopyTo(augmentedMsg, 0);
UInt32 remainder = 0xFFFFFFFF;
foreach (byte msgByte in augmentedMsg)
{
byte reversedMsgByte = Reverse(msgByte);
remainder = ((remainder << 8) | Convert.ToUInt32(reversedMsgByte)) ^ crc32_table[((remainder >> 24)) & 0xFF];
}
remainder = Reverse(~remainder);
return remainder;
}
Если я использую приведенный ниже код (который позволяет избежать увеличения сообщения), то получается правильный результат.
public static UInt32 GenerateCRC_32_from_Table(byte[] message)
{
UInt32 remainder = 0xFFFFFFFF;
foreach (byte msgByte in message)
{
byte reversedMsgByte = Reverse(msgByte);
remainder = (remainder << 8) ^ crc32_table[((remainder >> 24) ^ Convert.ToUInt32(reversedMsgByte)) & 0xFF];
}
remainder = Reverse(~remainder);
return remainder;
}
Reverse() и poly32, как указано в комментариях: **
const UInt32 poly32 = 0x04C11DB7;
public static UInt32 Reverse(UInt32 message)
{
UInt32 msgReversed = 0;
for (int i = 0; i < 32; i++)
{
msgReversed = ((message & 0x80000000) >> (31 - i)) | msgReversed;
message = message << 1;
}
return msgReversed;
}
public static byte Reverse(byte message)
{
byte msgReversed = 0;
for (int i = 0; i < 8; i++)
{
msgReversed = (byte)(((byte)((byte)(message) & 0x80) >> (7 - i)) | msgReversed);
message = (byte)(message << 1);
}
return msgReversed;
}