|
本帖最后由 QAQ 于 2019-4-9 10:54 编辑
- <?php
- set_time_limit(0);
- ini_set("memory_limit","1024M");
- function bin2int($bin){ //二进制字符串转整数
- return hexdec(bin2hex($bin));
- }
- function int2bin($int){ //整数转二进制字符串
- $hex = dechex($int);
- if(strlen($hex)&1){
- $hex = "0".$hex;
- }
- return hex2bin($hex);
- }
- /*
- Intel Hex 创建校验码 返回0~255
- 参数1(必须):要校验的数据
- 参数2(可选):最后1字节是否参与校验(0 或 1,默认为1)
- */
- function intelhex_check($bin,$r1b = 1){
- $len = strlen($bin)-!$r1b;
- $return = 0;
- for($i=0;$i<$len;$i++){
- $return+=ord($bin[$i]);
- $return&=255;
- }
- return (256-$return)&255;
- }
- /*
- Intel Hex 解码程序
- 参数1(必须):Intel Hex文本
- 参数2:错误码(可选变量):成功传出0 失败非0并返回空
- */
- function intelhex_decode($hex,&$err = 0){
- $err = 0;
- $al = array();
- $dt = array();
- $data_size =0;
- $ela = 0; //扩展线性地址记录
- $esa = 0; //扩展段地址记录
- $end = 0; //文件结束记录
- $retarr = array();
- $return = "";
- foreach(explode("\r\n",$hex) As $rn){
- $dd = "";
- if(!strlen($rn) || $rn[0] != ":") continue;
- $rn = @hex2bin(str_replace(":","",$rn));
- if($rn == null) { //非16进制字符
- $err = 1;
- return;
- }
- $len = strlen($rn);
- $ll = ord($rn[0]); //ll 是数据长度域,它代表记录当中数据字节(dd...)的数量.
- $aaaa = (ord($rn[1])<<8)+ord($rn[2])+($ela<<16)+($esa<<4); //aaaa 是地址域,它代表记录当中数据的起始地址.
- //$aaaa = ord($rn[1])<<8|ord($rn[2])|$ela<<16|$esa<<4; //如转换有错误请将此行代码解除注释,并注释上行代码
- $tt = ord($rn[3]);
- for($i=4;$i<$len-1;$i++) $dd .= $rn[$i];
- $cc = ord($rn[$len-1]); //cc 是校验和域,它表示这个记录的校验和.校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足.
- if(intelhex_check($rn,0) != $cc){ //校验错误
- $err = 2;
- return;
- } elseif(strlen($dd) != $ll){ //数据长度错误
- $err = 3;
- return;
- }
-
- switch($tt){ //tt 是代表HEX记录类型的域,它可能是以下数据当中的一个
- case 0:{ //00 数据记录
- $data_size = max($data_size,$aaaa+$ll); //更新数据长度
- $j = 4;
- for($i=$aaaa;$i<$aaaa+$ll;$i++){
- $retarr[$i] = $rn[$j++];
- }
- break;
- }
- case 1:{ //01 文件结束记录
- if($end) {
- $err = 4; //结束标志重复
- return;
- }
- $end = 1;
- break;
- }
- case 2:$esa=bin2int($dd);break; //02 扩展段地址记录
- case 4:$ela=bin2int($dd);break; //04 扩展线性地址记录
- default:{ //未知记录
- $err = 5;
- return;
- }
- }
- }
- $array_size = sizeof($retarr);
- if(!$data_size){ //没有读取到数据
- $err = 6;
- return;
- }elseif(!$end){ //没有结束标志
- $err = 7;
- return;
- } elseif($data_size < 0){ //数据长度溢出
- $err = 8;
- return;
- }
- $max_size = max($array_size,$data_size);
- for($i=0;$i<$max_size;$i++){
- $return .= isset($retarr[$i]) ? $retarr[$i] : chr(255);
- }
- return $return;
- }
- function intelhex_row_encode($aaaa,$tt,$dd=null){ //数据行编码 ll cc自动计算
- $return = chr(strlen($dd));
- if($aaaa <= 255) $return .=chr(0);
- $return .= int2bin($aaaa);
- $return .= chr($tt);
- $return .= $dd;
- $return .= chr(intelhex_check($return));
- return ":".strtoupper(bin2hex($return))."\r\n";
- }
- /*
- Intel Hex 编码程序
- 参数1(必须):二进制Ascii文本数据
- */
- function intelhex_encode($bin){
- $pc = 0;
- $return = "";
- foreach(str_split($bin,32) As $data){
- $pc_l = $pc&65535;
- $pc_h = $pc>>16;
- if($pc_l == 0 && $pc != 0){
- $return .= intelhex_row_encode(0,4,int2bin($pc_h));
- }
- $return .= intelhex_row_encode($pc_l,0,$data);
- $pc+=32;
- }
- $return .= intelhex_row_encode(0,1);
- return $return;
- }
- //===================================================
- $hex = intelhex_encode(file_get_contents("bin.bin")); //读入bin.bin并编码成hex
- file_put_contents("hex.hex",$hex); //将数据写入hex.hex
- file_put_contents("bin_.bin",intelhex_decode($hex,$err)); //再次解码hex.hex到bin_.bin
- echo $err; //输出错误码
- ?>
复制代码 |
|