.net 如何计算字符串的CRC32
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I calculate CRC32 of a string
提问by Nick Berardi
How do I calculate the CRC32 (Cyclic Redundancy Checksum) of a string in .NET?
如何计算 .NET 中字符串的 CRC32(循环冗余校验和)?
采纳答案by Pete
This guy seems to have your answer.
这家伙似乎有你的答案。
https://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net
https://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net
And in case the blog ever goes away or breaks the url, here's the github link:
如果博客消失或破坏了 url,这里是 github 链接:
Usage of the Crc32 class from the blog post:
博客文章中 Crc32 类的用法:
Crc32 crc32 = new Crc32();
String hash = String.Empty;
using (FileStream fs = File.Open("c:\myfile.txt", FileMode.Open))
foreach (byte b in crc32.ComputeHash(fs)) hash += b.ToString("x2").ToLower();
Console.WriteLine("CRC-32 is {0}", hash);
回答by SharpC
Since you seem to be looking to calculate the CRC32 of a string (rather than a file) there's a good example here: https://rosettacode.org/wiki/CRC-32#C.23
由于您似乎希望计算字符串(而不是文件)的 CRC32,这里有一个很好的例子:https: //rosettacode.org/wiki/CRC-32#C.23
The code should it ever disappear:
代码应该消失:
/// <summary>
/// Performs 32-bit reversed cyclic redundancy checks.
/// </summary>
public class Crc32
{
#region Constants
/// <summary>
/// Generator polynomial (modulo 2) for the reversed CRC32 algorithm.
/// </summary>
private const UInt32 s_generator = 0xEDB88320;
#endregion
#region Constructors
/// <summary>
/// Creates a new instance of the Crc32 class.
/// </summary>
public Crc32()
{
// Constructs the checksum lookup table. Used to optimize the checksum.
m_checksumTable = Enumerable.Range(0, 256).Select(i =>
{
var tableEntry = (uint)i;
for (var j = 0; j < 8; ++j)
{
tableEntry = ((tableEntry & 1) != 0)
? (s_generator ^ (tableEntry >> 1))
: (tableEntry >> 1);
}
return tableEntry;
}).ToArray();
}
#endregion
#region Methods
/// <summary>
/// Calculates the checksum of the byte stream.
/// </summary>
/// <param name="byteStream">The byte stream to calculate the checksum for.</param>
/// <returns>A 32-bit reversed checksum.</returns>
public UInt32 Get<T>(IEnumerable<T> byteStream)
{
try
{
// Initialize checksumRegister to 0xFFFFFFFF and calculate the checksum.
return ~byteStream.Aggregate(0xFFFFFFFF, (checksumRegister, currentByte) =>
(m_checksumTable[(checksumRegister & 0xFF) ^ Convert.ToByte(currentByte)] ^ (checksumRegister >> 8)));
}
catch (FormatException e)
{
throw new CrcException("Could not read the stream out as bytes.", e);
}
catch (InvalidCastException e)
{
throw new CrcException("Could not read the stream out as bytes.", e);
}
catch (OverflowException e)
{
throw new CrcException("Could not read the stream out as bytes.", e);
}
}
#endregion
#region Fields
/// <summary>
/// Contains a cache of calculated checksum chunks.
/// </summary>
private readonly UInt32[] m_checksumTable;
#endregion
}
and to use it:
并使用它:
var arrayOfBytes = Encoding.ASCII.GetBytes("The quick brown fox jumps over the lazy dog");
var crc32 = new Crc32();
Console.WriteLine(crc32.Get(arrayOfBytes).ToString("X"));
You can test the input / output values here: https://crccalc.com/
您可以在此处测试输入/输出值:https: //crccalc.com/
回答by spludlow
Using the logic from the previous answer, this was my take:
使用上一个答案的逻辑,这是我的看法:
public class CRC32
{
private readonly uint[] ChecksumTable;
private readonly uint Polynomial = 0xEDB88320;
public CRC32()
{
ChecksumTable = new uint[0x100];
for (uint index = 0; index < 0x100; ++index)
{
uint item = index;
for (int bit = 0; bit < 8; ++bit)
item = ((item & 1) != 0) ? (Polynomial ^ (item >> 1)) : (item >> 1);
ChecksumTable[index] = item;
}
}
public byte[] ComputeHash(Stream stream)
{
uint result = 0xFFFFFFFF;
int current;
while ((current = stream.ReadByte()) != -1)
result = ChecksumTable[(result & 0xFF) ^ (byte)current] ^ (result >> 8);
byte[] hash = BitConverter.GetBytes(~result);
Array.Reverse(hash);
return hash;
}
public byte[] ComputeHash(byte[] data)
{
using (MemoryStream stream = new MemoryStream(data))
return ComputeHash(stream);
}
}

