本文目录一览:
- 1、php crc16 移位算法 急急急!
- 2、关于php实现crc冗余算法的验证和补全问题
- 3、php 实现crc16验证 modbus该如何实现?
- 4、PHP CRC16 校验码的算法如何使用
- 5、php的crc32函数使用时需要注意的问题
php crc16 移位算法 急急急!
crc16校验计算过程:
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
注意:该步检查LSB应该是右移前的LSB,即第3步前的LSB。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.然后将数据的第二、三、四。。。N个8-bit字符。。。重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
理论上这样就完成了。
至于你说的前八位和后八位顺序倒换一下,其实就是$crc=($crc8)^($crc8),这样就倒换过来了。
修改以后的代码为:
function crc16($string,$crc=0xffff) {
for ( $x=0; $xstrlen( $string ); $x++ )
{
$crc = $crc ^ ord( $string[$x] );
for ($y = 0; $y 8; $y++)
{
if ( ($crc 0x0001) == 0x0001 )
$crc = ( ($crc 1 ) ^ 0xA001 );
else
$crc = $crc 1;
}
}
$crc = ($crc8) ^ ($crc8);
return $crc;
}
如果你位运算的基础不好的话,建议先理解位运算。
参考资料:
crc:
位运算:
希望有帮助到你。
关于php实现crc冗余算法的验证和补全问题
首先,要纠正一个概念上的错误,CRC算法是用来验证完整性的算法,它并不能提供错误修复的能力。
如果需要在PHP中使用CRC算法,可以直接使用PHP中的crc32函数。有关此函数的使用,可以参考以下链接:
如果需要在接收端进行错误的修复,则需要使用某种前向错误修正算法,比如里德-索罗门算法等,这些算法在PHP库中好像没有实现。相关的资料可以查看:
php 实现crc16验证 modbus该如何实现?
在工业控制中,Modbus RTU CRC16的校验码用的比较广泛,包括本人富士产品中,PC与伺服电机以及PC与VP系列的变频器的Modbus RTU通讯中都使用到了CRC16.
而对CRC16的计算的方式基本上有2种:第一种,使用双循环依照CRC的计算方法进行计算,第二种,采用查表的方式。本人愚钝无比,从网络上搜来的查表法都与实际的正确CRC16的结果有所差异,因此编写了一个小程序供自己使用。
软件的界面很简单,输入诸如“010303020014”的值,然后每2个字符作为一个字节,填入字节数,然后就可以计算出校验码,校验码的多项式为:X16+X15+X2+1.
程序界面如下:
实现的源代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Memo1: TMemo;
Label4: TLabel;
function CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//××××××××××××××××××××××××××
// CalCRC16用于计算Modbus RTU的CRC16
// 多项式公式为X16+X15+X2+1
//××××××××××××××××××××××××××
function TForm1.CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;
const
GENP=$A001; //多项式公式X16+X15+X2+1(1100 0000 0000 0101)
var
crc:Word;
i:Integer;
tmp:Byte;
procedure CalOneByte(AByte:Byte); //计算1个字节的校验码
var
j:Integer;
begin
crc:=crc xor AByte; //将数据与CRC寄存器的低8位进行异或
for j:=0 to 7 do //对每一位进行校验
begin
tmp:=crc and 1; //取出最低位
crc:=crc shr 1; //寄存器向右移一位
crc:=crc and $7FFF; //将最高位置0
if tmp=1 then //检测移出的位,如果为1,那么与多项式异或
crc:=crc xor GENP;
crc:=crc and $FFFF;
end;
end;
begin
crc:=$FFFF; //将余数设定为FFFF
for i:=AStart to AEnd do //对每一个字节进行校验
CalOneByte(AData[i]);
Result:=crc;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Data:array[0..255] of Byte;
i,j,Count:Integer;
Res:Word;
szData:string;
begin
szData:=Form1.Edit2.Text; //读入欲校验的字符串
Count:=StrToInt(form1.Edit3.Text); //读入需要计算的字符串长度
i:=1;
j:=0;
for j:=0 to Count-1 do
begin
if (i mod 2)=0 then //每2个字符放入一个字节中
i:=i+1;
if i=Length(szData) then
exit;
Data[j]:=StrToInt('$'+copy(szData,i,2)); //取出字符并转换为16进制数
i:=i+1;
end;
Res:=CalCRC16(Data,Low(Data),Count-1);
form1.Edit1.Text:=IntToHex(Res,4);
end;
end.
PHP CRC16 校验码的算法如何使用
I made this code to verify Transmition with Vantage Pro2 ( weather station ) based on CRC16-CCITT standard.
?php
// CRC16-CCITT validator
$crc_table = array(
0x0, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0xa50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0xc60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0xe70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0xa1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x2b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x8e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0xaf1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0xcc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0xed1, 0x1ef0);
$test = chr(0xC6).chr(0xCE).chr(0xA2).chr(0x03); // CRC16-CCITT = 0xE2B4
genCRC ($test);
function genCRC ($ptr)
{
$crc = 0x0000;
$crc_table = $GLOBALS['crc_table'];
for ($i = 0; $i strlen($ptr); $i++)
$crc = $crc_table[(($crc8) ^ ord($ptr[$i]))] ^ (($crc8) 0x00FFFF);
return $crc;
}
?
php的crc32函数使用时需要注意的问题
这篇文章主要介绍了php的crc32函数使用时需要注意的问题(不然就是坑)
,需要的朋友可以参考下
前几天写了一个分表程序,用的hash算法是crc32.分表的函数如下:
复制代码
代码如下:
function
_getHash($username)
{
$hash
=
crc32($username)
%
512;
return
$hash;
}
function
_getTable($username)
{
$hash
=
self::_getHash($username);
return
'user_'
.
$hash;
}
首先在本地32位window机上生成好数据并插入对应的表中。但是再把程序和数据传到服务器上(64为linux),发现查不到数据。经过排查后发现,原来服务器上crc32的结果和本地不同。再查php手册才知,crc32的接口原来和机器有关。
php手册的描述:
复制代码
代码如下:
Because
PHP's
integer
type
is
signed
many
crc32
checksums
will
result
in
negative
integers
on
32bit
platforms.
On
64bit
installations
all
crc32()
results
will
be
positive
integers
though.
crc32返回的结果在32位机上会产生溢出,所以结果可能为负数。而在64位机上不会溢出,所以总是正值。
CRC算法是按字长位数bit进行计算的。
crc32函数会按照php中的两个常量参考计算
PHP_INT_SIZE,PHP_INT_MAX
这两个常量的定义:
整型数的字长和平台有关,尽管通常最大值是大约二十亿(32
位有符号)。PHP
不支持无符号整数。Integer值的字长可以用常量PHP_INT_SIZE来表示,自
PHP
4.4.0
和
PHP
5.0.5后,最大值可以用常量PHP_INT_MAX来表示。
输出下32位中PHP_INT_SIZE:4,PHP_INT_MAX:2147483647
输出下64位中PHP_INT_SIZE:8,PHP_INT_MAX:9223372036854775807