有大佬知道这种效验怎么实现吗,找了很多网上代码效验都不正确
根据java示例,测试的代码:
public class Demo { public static void main(String[] args) { byte[] bytes = {1,2,3}; System.out.println(getCRC(bytes)); // 结果:24881 } public static int getCRC(byte[] bytes) { int crc = 0x0000; int polynomial = 0x1021; for (byte b : bytes){ for (int i = 0; i < 8; i++) { boolean bit = ((b >> (7-i)&1)==1); boolean c15 = ((crc >> 15 &1)==1); crc <<=1 ; if (c15^bit)crc^=polynomial; } } crc &= 0xffff; return crc; } }
然后根据java示例转PHP代码:
function getCRC($arr) { $crc = 0x0000; $polynomial = 0x1021; foreach ($arr AS $b){ for ($i=0;$i<8;$i++){ $bit = (($b>>(7-$i)&1)==1); $c15 = (($crc>>15 & 1)==1); $crc<<=1; if ($c15^$bit)$crc^=$polynomial; } } $crc &= 0xffff; return $crc; } //$arr1 = array(); //$str1 = '688c02340c32303231303830333130313000a135220531171637'; //$len = mb_strlen($str1); //for ($j=0;$j<($len/2);$j++){ // array_push($arr1,hexdec(mb_substr($str1,($j*2),2))); //} //echo implode(',',$arr1).PHP_EOL; $str = '68 8c 02 34 0c 32 30 32 31 30 38 30 33 31 30 31 30 00 a1 35 22 05 31 17 16 37'; $strArr = explode(' ',$str); $arr = array(); foreach ($strArr AS $value){ array_push($arr,hexdec($value)); } echo implode(',',$arr).PHP_EOL; echo getCRC($arr);
不知道这样子是否正确
注意: 根据Java示例,数组中的数字,不能大于 127,不能小于 -128
68 8c 02 34 0c 32 30 32 31 30 38 30 33 31 30 31 30 00 a1 35 22 05 31 17 16 37能帮我是试一下这一串看是否一样吗,大佬
这是16进制的字符串? 要试什么?
我只是小垃圾一个 不是大佬
他现在就是想把这个16进制用这个方式效验,但是我一直效验不对,你能帮我看看java和php用你这2块代码一样吗
不是很明白你是要怎么效验
我拿你给的十六进制字符串,然后转 十进制数字数组 ,java和php返回结果是一样的 数组:104,140,2,52,12,50,48,50,49,48,56,48,51,49,48,49,48,0,161,53,34,5,49,23,22,55 结果:39216
谢谢了,我这边在处理一下,这个文档有问题,他们需要CRC-16/XMODEM效验,文档没跟新
呃呃呃 好吧
能把你那个php 十六进制字符串,然后转 十进制数字数组 最后输出39216那个代码发一下吗兄弟
能把你php 那个 转10进制数组代码给我看看吗
呃呃呃 只是简单的转换 等一下
找到代码啦,谢谢兄弟了
已经放到代码里了
感谢
我按我理解给你翻译了一下,正常来说应该是跟java版一样的 public function getCRC(array $bytes){ $crc = 0x0000; $polynomial = 0x1021; foreach ($bytes as $b){ for ($i = 0 ; $i<8;$i++){ $bit = (($b >>(7-$i)& 1 )=== 1); $c15 = (($crc >>15 &1 ) === 1); $crc <<=1; if ($c15^$bit){ $crc^= $polynomial; } } } $crc &= 0xfff; return $crc; }
有个crc16类 你试试能不能用,里面有CRC16的XMODEM校验方法
class Crc16 { /** * CRC-16/IBM * @param $str * @return mixed */ public static function IBM($str) { return self::hash($str, 0x8005, 0, 0, true, true); } /** * CRC-16/MAXIM * @param $str * @return mixed */ public static function MAXIM($str) { return self::hash($str, 0x8005, 0, 0xffff, true, true); } /** * CRC-16/USB * @param $str * @return mixed */ public static function USB($str) { return self::hash($str, 0x8005, 0xffff, 0xffff, true, true); } /** * CRC-16/MODBUS * @param $str * @return mixed */ public static function MODBUS($str) { return self::hash($str, 0x8005, 0xffff, 0, true, true); } /** * CRC-16/CCITT * @param $str * @return mixed */ public static function CCITT($str) { return self::hash($str, 0x1021, 0, 0, true, true); } /** * CRC-16/CCITT-FALSE * @param $str * @return mixed */ public static function CCITT_FALSE($str) { return self::hash($str, 0x1021, 0xffff, 0, false, false); } /** * CRC-16/X25 * @param $str * @return mixed */ public static function X25($str) { return self::hash($str, 0x1021, 0xffff, 0xffff, true, true); } /** * CRC-16/XMODEM * @param $str * @return mixed */ public static function XMODEM($str) { return self::hash($str, 0x1021, 0, 0, false, false); } /** * CRC-16/DNP * @param $str * @return mixed */ public static function DNP($str) { return self::hash($str, 0x3d65, 0, 0xffff, true, true); } /** * 将一个字符按比特位进行反转 eg: 65 (01000001) --> 130(10000010) * @param $char * @return string $char */ private static function reverseChar($char) { $byte = ord($char); $tmp = 0; for ($i = 0; $i < 8; ++$i) { if ($byte & (1 << $i)) { $tmp |= (1 << (7 - $i)); } } return chr($tmp); } /** * 将一个字节流按比特位反转 eg: 'AB'(01000001 01000010) --> '\x42\x82'(01000010 10000010) * @param $str * @return mixed */ private static function reverseString($str) { $m = 0; $n = strlen($str) - 1; while ($m <= $n) { if ($m == $n) { $str[$m] = self::reverseChar($str[$m]); break; } $ord1 = self::reverseChar($str[$m]); $ord2 = self::reverseChar($str[$n]); $str[$m] = $ord2; $str[$n] = $ord1; $m++; $n--; } return $str; } /** * @param string $str 待校验字符串 * @param int $polynomial 二项式 * @param int $initValue 初始值 * @param int $xOrValue 输出结果前异或的值 * @param bool $inputReverse 输入字符串是否每个字节按比特位反转 * @param bool $outputReverse 输出是否整体按比特位反转 * @return int */ public static function hash($str, $polynomial, $initValue, $xOrValue, $inputReverse = false, $outputReverse = false) { $crc = $initValue; for ($i = 0; $i < strlen($str); $i++) { if ($inputReverse) { // 输入数据每个字节按比特位逆转 $c = ord(self::reverseChar($str[$i])); } else { $c = ord($str[$i]); } $crc ^= ($c << 8); for ($j = 0; $j < 8; ++$j) { if ($crc & 0x8000) { $crc = (($crc << 1) & 0xffff) ^ $polynomial; } else { $crc = ($crc << 1) & 0xffff; } } } if ($outputReverse) { // 把低地址存低位,即采用小端法将整数转换为字符串 $ret = pack('cc', $crc & 0xff, ($crc >> 8) & 0xff); // 输出结果按比特位逆转整个字符串 $ret = self::reverseString($ret); // 再把结果按小端法重新转换成整数 $arr = unpack('vshort', $ret); $crc = $arr['short']; } return $crc ^ $xOrValue; } }
private function crc16($string){ $string = pack('H*', $string); $crc = 0xFFFF; for ($x = 0; $x < strlen ($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; } } } $high8 = str_pad(dechex(floor($crc / 256)), 2, '0', STR_PAD_LEFT); $low8 = str_pad(dechex($crc % 256), 2, '0', STR_PAD_LEFT); return [strtoupper($high8), strtoupper($low8)]; }
我项目这样用的,可用
根据java示例,测试的代码:
然后根据java示例转PHP代码:
不知道这样子是否正确
注意: 根据Java示例,数组中的数字,不能大于 127,不能小于 -128
68 8c 02 34 0c 32 30 32 31 30 38 30 33 31 30 31 30 00 a1 35 22 05 31 17 16 37能帮我是试一下这一串看是否一样吗,大佬
这是16进制的字符串? 要试什么?
我只是小垃圾一个 不是大佬
他现在就是想把这个16进制用这个方式效验,但是我一直效验不对,你能帮我看看java和php用你这2块代码一样吗
不是很明白你是要怎么效验
我拿你给的十六进制字符串,然后转 十进制数字数组 ,java和php返回结果是一样的
数组:104,140,2,52,12,50,48,50,49,48,56,48,51,49,48,49,48,0,161,53,34,5,49,23,22,55
结果:39216
谢谢了,我这边在处理一下,这个文档有问题,他们需要CRC-16/XMODEM效验,文档没跟新
呃呃呃 好吧
能把你那个php 十六进制字符串,然后转 十进制数字数组 最后输出39216那个代码发一下吗兄弟
能把你php 那个 转10进制数组代码给我看看吗
呃呃呃 只是简单的转换 等一下
找到代码啦,谢谢兄弟了
已经放到代码里了
感谢
我按我理解给你翻译了一下,正常来说应该是跟java版一样的
public function getCRC(array $bytes){
$crc = 0x0000;
$polynomial = 0x1021;
foreach ($bytes as $b){
for ($i = 0 ; $i<8;$i++){
$bit = (($b >>(7-$i)& 1 )=== 1);
$c15 = (($crc >>15 &1 ) === 1);
$crc <<=1;
if ($c15^$bit){
$crc^= $polynomial;
}
}
}
$crc &= 0xfff;
return $crc;
}
有个crc16类 你试试能不能用,里面有CRC16的XMODEM校验方法
我项目这样用的,可用