还有两点重要声明如下: 1、只有当Bitstring的最高位为1,我们才将它与poly进行XOR运算,否则我们只是将Bitstring左移一位。 2、XOR运算的结果就是被操作位串Bitstring与poly的低W位进行XOR运算,因为最高位总为0。 逆风编程精品
呵呵,是不是有点头晕脑胀的感觉了?看不懂的话,再从头看一遍,其实是很好理解的。(就是一个XOR运算嘛!)
好啦,原理介绍到这里,下面我讲讲具体怎么编程。
由于速度的关系,CRC的实现主要是通过查表法,对于CRC-16和CRC-32,各自有一个现成的表,大家可以直接引入到程序中使用。(由于这两个表太长,在这里不列出来了,请读者自行在网络上查找,很容易找到的。)
如果我们没有这个表怎么办呢?或者你跟我一样,懒得自己输入?不用急,我们可以“自己动手,丰衣足食”。 你可能会说,自己编程来生成这个表,会不会太慢了?其实大可不必担心,因为我们是在汇编代码的级别进行运算的,而这个表只有区区256个双字,根本影响不了速度。
这个表的C语言描述如下: for (i = 0; i < 256; i ) { crc = i; for (j = 0; j < 8; j ) { if (crc & 1) crc = (crc >> 1) ^ 0xEDB88320; else crc >>= 1; } crc32tbl[i] = crc; }
生成表之后,就可以进行运算了。 我们的算法如下: 1、将寄存器向右边移动一个字节。 2、将刚移出的那个字节与我们的字符串中的新字节进行XOR运算,得出一个指向值表table[0..255]的索引。 3、将索引所指的表值与寄存器做XOR运算。 4、如果数据没有全部处理完,则跳到步骤1。
这个算法的C语言描述如下: temp = (oldcrc ^ abyte) & 0x000000FF; crc= (( oldcrc >> 8) & 0x00FFFFFF) ^ crc32tbl[temp]; return crc;
好啦,所有的东东都说完啦,最后献上一个完整的Win32Asm例子,请读者仔细研究吧! (汇编方面的CRC-32资料极少啊,我个人认为下面给出的是很宝贵的资料。)
;**************************************************** ;程序名称:演示CRC32原理 ;作者:罗聪 ;日期:2002-8-24 ;出处:http://laoluoc.yeah.net(老罗的缤纷天地) ;注意事项:如欲转载,请保持本程序的完整,并注明:转载自“老罗的缤纷天地”(http://laoluoc.yeah.net) ; ;特别感谢Win32ASM高手—— dREAMtHEATER 为我的代码作了相当好的优化! ;请各位前去 http://NoteXPad.yeah.net 下载他的小巧的“cool 记事本”—— NoteXPad 来试用!(100% Win32ASM 编写) ; ;****************************************************
.386 .model flat, stdcall option casemap:none
include windows.inc include kernel32.inc include user32.inc includelib kernel32.lib includelib user32.lib
WndProcproto :DWORD, :DWORD, :DWORD, :DWORD init_crc32tableproto arraycrc32 proto
.const IDC_BUTTON_OPENequ3000 IDC_EDIT_INPUT equ3001
.data szDlgName db"lc_dialog", 0 szTitle db"CRC demo by LC", 0 szTemplatedb"字符串 ""%s"" 的 CRC32 值是:%X", 0 crc32tbldd256 dup(0);CRC-32 table szBufferdb255 dup(0)
.data? szTextdb300 dup(?)
.code main: invoke GetModuleHandle, NULL invoke DialogBoxParam, eax, offset szDlgName, 0, WndProc, 0 invoke ExitProcess, eax
WndProc proc uses ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg == WM_CLOSE invoke EndDialog, hWnd, 0
.elseif uMsg == WM_COMMAND mov eax,wParam mov edx,eax shr edx,16 movzx eax, ax .if edx == BN_CLICKED .IF eax == IDCANCEL invoke EndDialog, hWnd, NULL .ELSEIF eax == IDC_BUTTON_OPEN || eax == IDOK ;****************************************** ;关键代码开始:(当当当当……) ;****************************************** ;取得用户输入的字符串: invoke GetDlgItemText, hWnd, IDC_EDIT_INPUT, addr szBuffer, 255
;初始化crc32table: invoke init_crc32table 本文章更多内容:<<上一页 - 1 - 2 - 3 - 下一页>> |