如题。
校验码系统是产生校验码并校验包括校验码在内的字符串的一套规则。
它可以防止在抄录和键入字符串时产生的错误。
一般生成 MD5 校验,也可以生成、进行简单、快速的 整数 校验。
谷歌开源,很实用的整数校验码生成代码。
1 文本格式
using System;
using System.Text;
/// <summary>
/// 按Google算法计算(string)的Checksum数值
/// </summary>
public static class ChecksumHelper
{
/// <summary>
/// 返回无符号整数的
/// </summary>
/// <param name="sURL"></param>
/// <returns></returns>
public static uint UintValue(string sURL)
{
uint ch = GoogleCH(sURL);
ch = (((ch / 7) << 2) | (((uint)(ch % 13)) & 7));
uint[] prbuf = new uint[20];
prbuf[0] = ch;
for (int i = 1; i < 20; i++)
{
prbuf[i] = prbuf[i - 1] - 9;
}
ch = GoogleCH(c32to8bit(prbuf), 80);
return ch;
}
/// <summary>
/// 返回有符号的数值
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static int Value(string url)
{
return (int)UintValue(url);
}
#region 算法核心
private static uint GOOGLE_MAGIC = 0xE6359A60;
private static uint zeroFill(uint a, int b)
{
checked
{
uint z = 0x80000000;
if (Convert.ToBoolean(z & a))
{
a = (a >> 1);
a &= (~z);
a |= 0x40000000;
a = (a >> (b - 1));
}
else
{
a = (a >> b);
}
}
return a;
}
private static uint[] mix(uint a, uint b, uint c)
{
a -= b; a -= c; a ^= (uint)(zeroFill(c, 13));
b -= c; b -= a; b ^= (uint)(a << 8);
c -= a; c -= b; c ^= (uint)(zeroFill(b, 13));
a -= b; a -= c; a ^= (uint)(zeroFill(c, 12));
b -= c; b -= a; b ^= (uint)(a << 16);
c -= a; c -= b; c ^= (uint)(zeroFill(b, 5));
a -= b; a -= c; a ^= (uint)(zeroFill(c, 3));
b -= c; b -= a; b ^= (uint)(a << 10);
c -= a; c -= b; c ^= (uint)(zeroFill(b, 15));
return new uint[3] { a, b, c };
}
private static uint GoogleCH(uint[] url, uint length, uint init)
{
if (length == 0)
{
length = (uint)url.Length;
}
uint a, b;
a = b = 0x9E3779B9;
uint c = init;
int k = 0;
uint len = length;
uint[] m_mix = new uint[3];
while (len >= 12)
{
a += (uint)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));
b += (uint)(url[k + 4] + (url[k + 5] << 8) + (url[k + 6] << 16) + (url[k + 7] << 24));
c += (uint)(url[k + 8] + (url[k + 9] << 8) + (url[k + 10] << 16) + (url[k + 11] << 24));
m_mix = mix(a, b, c);
a = m_mix[0]; b = m_mix[1]; c = m_mix[2];
k += 12;
len -= 12;
}
c += length;
// all the case statements fall through
switch (len)
{
case 11:
{
c += (uint)(url[k + 10] << 24);
c += (uint)(url[k + 9] << 16);
c += (uint)(url[k + 8] << 8);
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 10:
{
c += (uint)(url[k + 9] << 16);
c += (uint)(url[k + 8] << 8);
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 9:
{
c += (uint)(url[k + 8] << 8);
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
// the first byte of c is reserved for the length
case 8:
{
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 7:
{
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 6:
{
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 5:
{
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 4:
{
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 3:
{
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 2:
{
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 1:
{
a += (uint)(url[k + 0]);
break;
}
case 0:
//nothing left to add
break;
}
m_mix = mix(a, b, c);
// report the result
return m_mix[2];
}
private static uint GoogleCH(string url, uint length)
{
uint[] m_urluint = new uint[url.Length];
for (int i = 0; i < url.Length; i++)
{
m_urluint[i] = url[i];
}
return GoogleCH(m_urluint, length, GOOGLE_MAGIC);
}
private static uint GoogleCH(string sURL)
{
return GoogleCH(sURL, 0);
}
private static uint GoogleCH(uint[] url, uint length)
{
return GoogleCH(url, length, GOOGLE_MAGIC);
}
private static uint[] c32to8bit(uint[] arr32)
{
uint[] arr8 = new uint[arr32.GetLength(0) * 4 + 3];
for (int i = 0; i < arr32.GetLength(0); i++)
{
for (int bitOrder = i * 4; bitOrder <= i * 4 + 3; bitOrder++)
{
arr8[bitOrder] = arr32[i] & 255;
arr32[i] = zeroFill(arr32[i], 8);
}
}
return arr8;
}
#endregion
}
POWER BY TRUFFER.CN
BY 315SOFT.COM
2 代码格式
using System;
using System.Text;
/// <summary>
/// 按Google算法计算(string)的Checksum数值
/// </summary>
public static class ChecksumHelper
{
/// <summary>
/// 返回无符号整数的
/// </summary>
/// <param name="sURL"></param>
/// <returns></returns>
public static uint UintValue(string sURL)
{
uint ch = GoogleCH(sURL);
ch = (((ch / 7) << 2) | (((uint)(ch % 13)) & 7));
uint[] prbuf = new uint[20];
prbuf[0] = ch;
for (int i = 1; i < 20; i++)
{
prbuf[i] = prbuf[i - 1] - 9;
}
ch = GoogleCH(c32to8bit(prbuf), 80);
return ch;
}
/// <summary>
/// 返回有符号的数值
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static int Value(string url)
{
return (int)UintValue(url);
}
#region 算法核心
private static uint GOOGLE_MAGIC = 0xE6359A60;
private static uint zeroFill(uint a, int b)
{
checked
{
uint z = 0x80000000;
if (Convert.ToBoolean(z & a))
{
a = (a >> 1);
a &= (~z);
a |= 0x40000000;
a = (a >> (b - 1));
}
else
{
a = (a >> b);
}
}
return a;
}
private static uint[] mix(uint a, uint b, uint c)
{
a -= b; a -= c; a ^= (uint)(zeroFill(c, 13));
b -= c; b -= a; b ^= (uint)(a << 8);
c -= a; c -= b; c ^= (uint)(zeroFill(b, 13));
a -= b; a -= c; a ^= (uint)(zeroFill(c, 12));
b -= c; b -= a; b ^= (uint)(a << 16);
c -= a; c -= b; c ^= (uint)(zeroFill(b, 5));
a -= b; a -= c; a ^= (uint)(zeroFill(c, 3));
b -= c; b -= a; b ^= (uint)(a << 10);
c -= a; c -= b; c ^= (uint)(zeroFill(b, 15));
return new uint[3] { a, b, c };
}
private static uint GoogleCH(uint[] url, uint length, uint init)
{
if (length == 0)
{
length = (uint)url.Length;
}
uint a, b;
a = b = 0x9E3779B9;
uint c = init;
int k = 0;
uint len = length;
uint[] m_mix = new uint[3];
while (len >= 12)
{
a += (uint)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));
b += (uint)(url[k + 4] + (url[k + 5] << 8) + (url[k + 6] << 16) + (url[k + 7] << 24));
c += (uint)(url[k + 8] + (url[k + 9] << 8) + (url[k + 10] << 16) + (url[k + 11] << 24));
m_mix = mix(a, b, c);
a = m_mix[0]; b = m_mix[1]; c = m_mix[2];
k += 12;
len -= 12;
}
c += length;
// all the case statements fall through
switch (len)
{
case 11:
{
c += (uint)(url[k + 10] << 24);
c += (uint)(url[k + 9] << 16);
c += (uint)(url[k + 8] << 8);
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 10:
{
c += (uint)(url[k + 9] << 16);
c += (uint)(url[k + 8] << 8);
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 9:
{
c += (uint)(url[k + 8] << 8);
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
// the first byte of c is reserved for the length
case 8:
{
b += (uint)(url[k + 7] << 24);
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 7:
{
b += (uint)(url[k + 6] << 16);
b += (uint)(url[k + 5] << 8);
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 6:
{
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 5:
{
b += (uint)(url[k + 4]);
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 4:
{
a += (uint)(url[k + 3] << 24);
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 3:
{
a += (uint)(url[k + 2] << 16);
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 2:
{
a += (uint)(url[k + 1] << 8);
a += (uint)(url[k + 0]);
break;
}
case 1:
{
a += (uint)(url[k + 0]);
break;
}
case 0:
//nothing left to add
break;
}
m_mix = mix(a, b, c);
// report the result
return m_mix[2];
}
private static uint GoogleCH(string url, uint length)
{
uint[] m_urluint = new uint[url.Length];
for (int i = 0; i < url.Length; i++)
{
m_urluint[i] = url[i];
}
return GoogleCH(m_urluint, length, GOOGLE_MAGIC);
}
private static uint GoogleCH(string sURL)
{
return GoogleCH(sURL, 0);
}
private static uint GoogleCH(uint[] url, uint length)
{
return GoogleCH(url, length, GOOGLE_MAGIC);
}
private static uint[] c32to8bit(uint[] arr32)
{
uint[] arr8 = new uint[arr32.GetLength(0) * 4 + 3];
for (int i = 0; i < arr32.GetLength(0); i++)
{
for (int bitOrder = i * 4; bitOrder <= i * 4 + 3; bitOrder++)
{
arr8[bitOrder] = arr32[i] & 255;
arr32[i] = zeroFill(arr32[i], 8);
}
}
return arr8;
}
#endregion
}