|
CRC32算法(C++轉(zhuǎn)JavaScript) 收藏
這段時(shí)間我在研究一下HTML文件傳輸?shù)膯栴},但我研究的東西在發(fā)送文件過程中沒有加入校驗(yàn)碼,很多人都知道,網(wǎng)絡(luò)傳輸會(huì)存在數(shù)據(jù)丟失,錯(cuò)誤等問題,所以要自行加入校驗(yàn)碼。 在網(wǎng)上看了一些校驗(yàn)算法,發(fā)覺CRC16和CRC32相對(duì)比較簡(jiǎn)單(因?yàn)槲业奈募邮斩耸乔度胧较到y(tǒng),所以不能太復(fù)雜,以免浪費(fèi)資源),因此在網(wǎng)上找了一個(gè)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; } //開始計(jì)算CRC32校驗(yàn)值 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; } //開始計(jì)算CRC32校驗(yàn)值 Crc=0xffffffff; for(int i=0; i<len; i++){ Crc = (Crc >> 8)^ Crc32Table[(Crc & 0xFF) ^ InStr[i]]; } Crc ^= 0xFFFFFFFF; return Crc; } 上面的代碼來網(wǎng)絡(luò),本人經(jīng)過測(cè)試,在VC++中可以正常使用,而且結(jié)果也是正常的。 因?yàn)槲沂怯门cHTML,所以我想利用JS算出校驗(yàn)碼后,再發(fā)送。但由于我不太了解JS所以,只有在網(wǎng)上找找例子。因此,我在網(wǎng)上找了一段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; } 這段代碼也是來自網(wǎng)絡(luò)的,我也研究過,算法上是一模一樣,而且一些操作符名稱上是一樣的,>>這是移位,^這是位異或,&這是位與。 經(jīng)過驗(yàn)證,發(fā)現(xiàn)了一些JS與C++運(yùn)算符的上差別:
1、>>這個(gè)是右位移,但是 它移動(dòng)后并不像C++中的>>在前面補(bǔ)零,而是在前補(bǔ)1(可能是最高位為1就補(bǔ)1,為零就補(bǔ)零),所以運(yùn)算出來的結(jié)果完全不相同。
2、在JS中,字符與上一個(gè)16進(jìn)制數(shù),結(jié)果是一個(gè)0,即‘a’&0xff 等于0,JS不同C++,C++中字符與上一個(gè)16進(jìn)制數(shù),它會(huì)自動(dòng)轉(zhuǎn)成16進(jìn)行數(shù)再進(jìn)行運(yùn)算,但在JS中與上的值就明顯不正確。
下面是我經(jīng)過修改的結(jié)果,而且通過了我的驗(yàn)證
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; } 修改成上面的函數(shù)后,輸出結(jié)果是一個(gè)10進(jìn)制數(shù),可能經(jīng)過轉(zhuǎn)換后,以16進(jìn)制顯示,這里我就不再說明了。 本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/bakasen/archive/2010/11/29/6043797.aspx
|
|
|