CRC32算法(C++转JavaScript) 收藏
这段时间我在研究一下HTML文件传输的问题,但我研究的东西在发送文件过程中没有加入校验码,很多人都知道,网络传输会存在数据丢失,错误等问题,所以要自行加入校验码。 在网上看了一些校验算法,发觉CRC16和CRC32相对比较简单(因为我的文件接收端是嵌入式系统,所以不能太复杂,以免浪费资源),因此在网上找了一个C++的CRC32的算法,具体如下:
view plaincopy to clipboardprint?
unsigned int GetCrc32(char* InStr,unsigned int len){ //生成Crc32的查询表 unsigned int Crc32Table[256]; int i,j; unsigned int Crc; for (i = 0; i < 256; i++) { Crc = i; for (j = 0; j < 8; j++) { if (Crc & 1) Crc = (Crc >> 1) ^ 0xEDB88320; else Crc >>= 1; } Crc32Table[i] = Crc; } //开始计算CRC32校验值 Crc=0xffffffff; for(int i=0; i<len; i++){ Crc = (Crc >> 8)^ Crc32Table[(Crc & 0xFF) ^ InStr[i]]; } Crc ^= 0xFFFFFFFF; return Crc; } unsigned int GetCrc32(char* InStr,unsigned int len){ //生成Crc32的查询表 unsigned int Crc32Table[256]; int i,j; unsigned int Crc; for (i = 0; i < 256; i++) { Crc = i; for (j = 0; j < 8; j++) { if (Crc & 1) Crc = (Crc >> 1) ^ 0xEDB88320; else Crc >>= 1; } Crc32Table[i] = Crc; } //开始计算CRC32校验值 Crc=0xffffffff; for(int i=0; i<len; i++){ Crc = (Crc >> 8)^ Crc32Table[(Crc & 0xFF) ^ InStr[i]]; } Crc ^= 0xFFFFFFFF; return Crc; } 上面的代码来网络,本人经过测试,在VC++中可以正常使用,而且结果也是正常的。 因为我是用与HTML,所以我想利用JS算出校验码后,再发送。但由于我不太了解JS所以,只有在网上找找例子。因此,我在网上找了一段JS代码
view plaincopy to clipboardprint?
function makeCrc32Table() { if (typeof(window.crc32Table) != "undefined") return; window.crc32Table = new Array(256); for (var i = 0; i < 256; i++) { var k = i; for (var j = 0; j < 8; j++) if (k & 1) k = (k >> 1) ^ 0xedb88320; else k >>= 1; crc32Table[i] = k; } } function crc32(str) { makeCrc32Table(); if (typeof str != "string") str = "" + str; var crc = 0xffffffff; for (var i = 0; i < str.length; i++) { var code = str.charCodeAt(i); if (code > 0xff) { crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code & 0xff)]; crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code >> 8)]; } else crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ code]; } return crc ^ 0xffffffff; } function makeCrc32Table() { if (typeof(window.crc32Table) != "undefined") return; window.crc32Table = new Array(256); for (var i = 0; i < 256; i++) { var k = i; for (var j = 0; j < 8; j++) if (k & 1) k = (k >> 1) ^ 0xedb88320; else k >>= 1; crc32Table[i] = k; } } function crc32(str) { makeCrc32Table(); if (typeof str != "string") str = "" + str; var crc = 0xffffffff; for (var i = 0; i < str.length; i++) { var code = str.charCodeAt(i); if (code > 0xff) { crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code & 0xff)]; crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code >> 8)]; } else crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ code]; } return crc ^ 0xffffffff; } 这段代码也是来自网络的,我也研究过,算法上是一模一样,而且一些操作符名称上是一样的,>>这是移位,^这是位异或,&这是位与。 经过验证,发现了一些JS与C++运算符的上差别:
1、>>这个是右位移,但是 它移动后并不像C++中的>>在前面补零,而是在前补1(可能是最高位为1就补1,为零就补零),所以运算出来的结果完全不相同。
2、在JS中,字符与上一个16进制数,结果是一个0,即‘a’&0xff 等于0,JS不同C++,C++中字符与上一个16进制数,它会自动转成16进行数再进行运算,但在JS中与上的值就明显不正确。
下面是我经过修改的结果,而且通过了我的验证
view plaincopy to clipboardprint?
function GetCrc32(Instr) { if(typeof(window.Crc32Table)!="undefined")return; window.Crc32Table=new Array(256); var i,j; var Crc; for(i=0; i<256; i++) { Crc=i; for(j=0; j<8; j++) { if(Crc & 1) Crc=((Crc >> 1)& 0x7FFFFFFF) ^ 0xEDB88320; else Crc=((Crc >> 1)& 0x7FFFFFFF); } Crc32Table[i]=Crc; } if (typeof Instr != "string") Instr = "" + Instr; Crc=0xFFFFFFFF; for(i=0; i<Instr.length; i++) Crc=((Crc >> 8)&0x00FFFFFF) ^ Crc32Table[(Crc & 0xFF)^ Instr.charCodeAt(i)]; Crc ^=0xFFFFFFFF; return Crc; } function GetCrc32(Instr) { if(typeof(window.Crc32Table)!="undefined")return; window.Crc32Table=new Array(256); var i,j; var Crc; for(i=0; i<256; i++) { Crc=i; for(j=0; j<8; j++) { if(Crc & 1) Crc=((Crc >> 1)& 0x7FFFFFFF) ^ 0xEDB88320; else Crc=((Crc >> 1)& 0x7FFFFFFF); } Crc32Table[i]=Crc; } if (typeof Instr != "string") Instr = "" + Instr; Crc=0xFFFFFFFF; for(i=0; i<Instr.length; i++) Crc=((Crc >> 8)&0x00FFFFFF) ^ Crc32Table[(Crc & 0xFF)^ Instr.charCodeAt(i)]; Crc ^=0xFFFFFFFF; return Crc; } 修改成上面的函数后,输出结果是一个10进制数,可能经过转换后,以16进制显示,这里我就不再说明了。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bakasen/archive/2010/11/29/6043797.aspx
|
|