本文目錄一覽:
- 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
原創文章,作者:0X3NK,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/130372.html