设为首页收藏本站帮助中心
查看: 5238|回复: 5
收起左侧

[PHP/ASP/JSP] 64位PHP7.3.1版Intel HEX格式十六进制文本与bin格式互转 编解码程序源码 V1.0测试版

[复制链接]
发表于 2019-4-9 10:52:45 | 显示全部楼层 |阅读模式
本帖最后由 QAQ 于 2019-4-9 10:54 编辑

批注 2019-04-09 104955.png
批注 2019-04-09 104917.png
批注 2019-04-09 104714.png

  1. <?php
  2. set_time_limit(0);
  3. ini_set("memory_limit","1024M");




  4. function bin2int($bin){                //二进制字符串转整数
  5.         return hexdec(bin2hex($bin));
  6. }

  7. function int2bin($int){                //整数转二进制字符串
  8.         $hex = dechex($int);
  9.         if(strlen($hex)&1){
  10.         $hex = "0".$hex;
  11.         }
  12.         return hex2bin($hex);
  13. }



  14. /*
  15. Intel Hex 创建校验码 返回0~255
  16. 参数1(必须):要校验的数据
  17. 参数2(可选):最后1字节是否参与校验(0 或 1,默认为1)
  18. */

  19. function intelhex_check($bin,$r1b = 1){
  20.         $len = strlen($bin)-!$r1b;
  21.         $return = 0;
  22.         for($i=0;$i<$len;$i++){
  23.                 $return+=ord($bin[$i]);
  24.                 $return&=255;
  25.         }
  26.         return (256-$return)&255;

  27. }


  28. /*
  29.         Intel Hex 解码程序
  30.         参数1(必须):Intel Hex文本
  31.         参数2:错误码(可选变量):成功传出0 失败非0并返回空
  32. */
  33. function intelhex_decode($hex,&$err = 0){
  34.         $err = 0;
  35.         $al = array();
  36.         $dt = array();       
  37.         $data_size =0;
  38.         $ela = 0;        //扩展线性地址记录
  39.         $esa = 0;        //扩展段地址记录
  40.         $end = 0;        //文件结束记录
  41.         $retarr = array();
  42.         $return = "";
  43.         foreach(explode("\r\n",$hex) As $rn){
  44.                 $dd = "";
  45.                 if(!strlen($rn) || $rn[0] != ":") continue;
  46.                 $rn = @hex2bin(str_replace(":","",$rn));
  47.                 if($rn == null) {        //非16进制字符
  48.                         $err = 1;
  49.                         return;
  50.                         }
  51.                 $len = strlen($rn);
  52.                         $ll = ord($rn[0]);        //ll 是数据长度域,它代表记录当中数据字节(dd...)的数量.
  53.                         $aaaa = (ord($rn[1])<<8)+ord($rn[2])+($ela<<16)+($esa<<4);        //aaaa 是地址域,它代表记录当中数据的起始地址.
  54.                         //$aaaa = ord($rn[1])<<8|ord($rn[2])|$ela<<16|$esa<<4;                //如转换有错误请将此行代码解除注释,并注释上行代码
  55.                         $tt = ord($rn[3]);
  56.                         for($i=4;$i<$len-1;$i++) $dd .= $rn[$i];
  57.                         $cc = ord($rn[$len-1]);        //cc 是校验和域,它表示这个记录的校验和.校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足.
  58.                         if(intelhex_check($rn,0) != $cc){        //校验错误
  59.                                 $err = 2;
  60.                                 return;
  61.                         } elseif(strlen($dd) != $ll){                //数据长度错误
  62.                                 $err = 3;
  63.                                 return;
  64.                         }
  65.                        
  66.                         switch($tt){        //tt 是代表HEX记录类型的域,它可能是以下数据当中的一个
  67.                                 case 0:{        //00 数据记录
  68.                                         $data_size = max($data_size,$aaaa+$ll);                //更新数据长度
  69.                                         $j = 4;
  70.                                         for($i=$aaaa;$i<$aaaa+$ll;$i++){
  71.                                                 $retarr[$i] = $rn[$j++];
  72.                                         }
  73.                                         break;
  74.                                 }       
  75.                                 case 1:{        //01 文件结束记录
  76.                                 if($end) {
  77.                                         $err = 4;        //结束标志重复
  78.                                         return;
  79.                                 }
  80.                                         $end = 1;
  81.                                         break;
  82.                                 }               
  83.                                 case 2:$esa=bin2int($dd);break;        //02 扩展段地址记录
  84.                                 case 4:$ela=bin2int($dd);break;        //04 扩展线性地址记录
  85.                                 default:{                //未知记录
  86.                                         $err = 5;
  87.                                         return;
  88.                                 }
  89.                         }
  90.                 }
  91.         $array_size = sizeof($retarr);
  92.         if(!$data_size){                //没有读取到数据
  93.                 $err = 6;
  94.                 return;
  95.                 }elseif(!$end){                //没有结束标志
  96.                 $err = 7;
  97.                 return;
  98.         } elseif($data_size < 0){        //数据长度溢出
  99.                 $err = 8;
  100.                 return;
  101.         }
  102.                 $max_size = max($array_size,$data_size);
  103.                 for($i=0;$i<$max_size;$i++){
  104.                         $return .= isset($retarr[$i]) ? $retarr[$i] : chr(255);
  105.                 }

  106.         return $return;

  107. }

  108. function intelhex_row_encode($aaaa,$tt,$dd=null){                //数据行编码 ll cc自动计算
  109.         $return = chr(strlen($dd));
  110.         if($aaaa <= 255) $return .=chr(0);
  111.         $return .= int2bin($aaaa);
  112.         $return .= chr($tt);
  113.         $return .= $dd;
  114.         $return .= chr(intelhex_check($return));
  115.         return ":".strtoupper(bin2hex($return))."\r\n";
  116. }


  117. /*
  118.         Intel Hex 编码程序
  119.         参数1(必须):二进制Ascii文本数据
  120. */
  121. function intelhex_encode($bin){
  122.         $pc = 0;
  123.         $return = "";
  124.         foreach(str_split($bin,32) As $data){
  125.                 $pc_l = $pc&65535;
  126.                 $pc_h = $pc>>16;
  127.                 if($pc_l == 0 && $pc != 0){
  128.                         $return .= intelhex_row_encode(0,4,int2bin($pc_h));
  129.                 }
  130.                 $return .= intelhex_row_encode($pc_l,0,$data);
  131.                 $pc+=32;
  132.         }
  133.         $return .= intelhex_row_encode(0,1);
  134.         return $return;
  135. }


  136. //===================================================
  137. $hex = intelhex_encode(file_get_contents("bin.bin"));        //读入bin.bin并编码成hex
  138. file_put_contents("hex.hex",$hex);                        //将数据写入hex.hex


  139. file_put_contents("bin_.bin",intelhex_decode($hex,$err));        //再次解码hex.hex到bin_.bin
  140. echo $err;        //输出错误码

  141. ?>


复制代码

相关帖子

回复

使用道具 举报

发表于 2019-4-9 11:40:41 | 显示全部楼层
谢谢大大,看看吧
回复 支持 反对

使用道具 举报

发表于 2019-4-9 18:53:10 来自手机 | 显示全部楼层
来看看快快快
回复 支持 反对

使用道具 举报

发表于 2019-4-10 06:53:25 来自手机 | 显示全部楼层
我也666,看看吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则