V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hxnets
V2EX  ›  PHP

PHP 数据追加数据后的长度问题

  •  
  •   hxnets · 2020-11-27 16:06:31 +08:00 · 2563 次点击
    这是一个创建于 1463 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一条数据 205,转为 8 位字节后的值为 cd000000, 现在对每字节加 0x33,结果值为 100333333,现在想保持这个数据长度为 8 位。

    咨询了一些朋友说是要判断进位情况,然后取低位,弄判断没太明白应该怎么处理,老哥们帮帮我

    22 条回复    2020-12-03 09:26:04 +08:00
    hxnets
        1
    hxnets  
    OP
       2020-11-27 16:22:20 +08:00
    附我这边加 33 的代码

    /**
    * 数据加 0x33
    * @param $data //数据
    * @return string
    */
    function addData33($data)
    {
    $data = str_split($data,2);
    for($i = 0;$i<count($data);$i++)
    {
    $data[$i] = dechex(hexdec($data[$i]) + 0x33);
    }
    return implode("",$data);
    }
    zjsxwc
        2
    zjsxwc  
       2020-11-27 16:52:54 +08:00
    首先默认现在芯片都是小端字节排序的,因为大端字节排序的基本都已经绝种。

    然后默认你 205 是无符号整数,不然如果是有符号整数,还会涉及补吗转化更加麻烦,
    所以你无符号 205 转为 8 个字节 64 位表示是 “cd 00 00 00 00 00 00 00”这个表示中每一字符代表 4 个位的二进制,

    对每字节加 0x33,就是 整体加 “33 33 33 33 33 33 33 33” 也就是十进制 3689348814741910500

    所以如果你$data 是 16 进制字符串的话可以这么写
    function addData33($data)
    {
    $int = null;
    eval("\$int = 0x". $data.";");
    return 3689348814741910500+$int;
    }
    zjsxwc
        3
    zjsxwc  
       2020-11-27 17:00:39 +08:00
    function addData33($data)
    {
    $int = null;
    eval("\$int = 0x". $data.";");
    $r = 3689348814741910500+$int;
    return sprintf("%016x", $r);
    }
    lovecy
        4
    lovecy  
       2020-11-27 17:14:06 +08:00
    为何要加 0x33,为何要保持 8 位。。
    说实话看了问题和下面的回复,一脸懵逼,踏入了未知领域
    zjsxwc
        5
    zjsxwc  
       2020-11-27 17:36:28 +08:00 via Android
    3689348814741910500 这个值可能不对,因为我是网页计算器算的,但是由于 js 天生不支持 64 位整数所以网页计算器算了这个错误值,你直接用 0x33 33 33 33 33 33 33 33 代替就好了。
    hxnets
        6
    hxnets  
    OP
       2020-11-27 17:42:20 +08:00
    @zjsxwc 首先感谢老哥的回复,我这边现在是处理 dlt645 协议,协议要求要对数据域的每字节+33,当充值此处小的时候没关系,但是当充值此处 200 以上的时候,数据会进位,协议要求的字节长度是 8 位,这时候产生的数据是 9 位,导致指令出错,现在应该是要对数据取低位。

    所以 如果有一个字符串 我应该怎么取它的低 8 位?
    hxnets
        7
    hxnets  
    OP
       2020-11-27 17:42:28 +08:00
    @lovecy @zjsxwc 首先感谢老哥的回复,我这边现在是处理 dlt645 协议,协议要求要对数据域的每字节+33,当充值此处小的时候没关系,但是当充值此处 200 以上的时候,数据会进位,协议要求的字节长度是 8 位,这时候产生的数据是 9 位,导致指令出错,现在应该是要对数据取低位。

    所以 如果有一个字符串 我应该怎么取它的低 8 位?
    si
        8
    si  
       2020-11-27 17:59:00 +08:00
    不太明白“想保持这个数据长度为 8 位”是什么意思,建议直接给出预计结果是什么,比如 00,33,33,33 。或者直接贴文档说明。
    zjsxwc
        9
    zjsxwc  
       2020-11-27 18:12:20 +08:00 via Android
    @hxnets 看来我多虑了,这种根本不用考虑大小端和有无符号整数,

    直接无脑读两个字符处理两个字符就好了
    function addData33($data)
    {
    $data = str_split($data,2);
    for($i = 0;$i<count($data);$i++)
    {
    $data[$i] = dechex((hexdec($data[$i]) + 0x33)&0xff);
    }
    return implode("",$data);
    }
    zjsxwc
        10
    zjsxwc  
       2020-11-27 18:24:07 +08:00 via Android
    function addData33($data)
    {
    $data = str_split($data,2);
    for($i = 0;$i<count($data);$i++)
    {
    $data[$i] = sprintf("%02x",(hexdec($data[$i]) + 0x33)&0xff);
    }
    return implode("",$data);
    }
    xxbutoo
        11
    xxbutoo  
       2020-11-27 18:32:43 +08:00
    @zjsxwc 你说的这些知识 属于哪块领域啊?
    zjsxwc
        12
    zjsxwc  
       2020-11-27 18:43:05 +08:00 via Android
    @xxbutoo 计算机原理啊
    ETiV
        13
    ETiV  
       2020-11-27 19:00:44 +08:00
    我也看的一脸懵逼,

    但是搜到篇这个: https://blog.csdn.net/u012351051/article/details/77869547

    末尾写到:

    A4 56 79 38-具体数据,分析时,应减 33,所以为:

    A4-33=71
    56-33=23
    79-33=46
    38-33=5

    实际的电表数为:54623.71 度

    是不是你的 205,是不需要从数值转成 hex 的,而是用字面量表达成 05 02 00 00,再+33h,变成 38 35 33 33 这样的表达方式

    (考虑到十进制最大就是 99,+33h 也不会超 FF )
    947211232
        14
    947211232  
       2020-11-27 23:40:31 +08:00
    C#语言,你处理的是数据域,应该可以它山之石 https://www.cnblogs.com/myzony/p/10897895.html
    947211232
        15
    947211232  
       2020-11-28 00:12:09 +08:00
    hxnets
        16
    hxnets  
    OP
       2020-11-28 11:24:48 +08:00
    @si 协议要求的比如说充值数量和充值读书的字节长度是 8 位,其实这个问题就是 数值进位后 的问题,应该取值的低字节位
    hxnets
        17
    hxnets  
    OP
       2020-11-28 11:25:53 +08:00
    @947211232 感谢老哥 这个我也有参考,问题是 我看了现在的大部分的相关系统 都没有对 进位的情况作处理,这个问题要充值度数很大的情况下才会出现
    hxnets
        18
    hxnets  
    OP
       2020-11-28 11:26:44 +08:00
    @zjsxwc 啊。。。这 我试试看
    hxnets
        19
    hxnets  
    OP
       2020-11-28 11:28:25 +08:00
    @ETiV 数据域的总长度是有要求的,另外就是数据要转换成 二进制发送,使用 hextobin 的时候 如果字符串是 奇数位就会出错
    hxnets
        20
    hxnets  
    OP
       2020-11-28 11:33:32 +08:00
    @zjsxwc 那这样的话,充值次数的值就是 38 ?
    si
        21
    si  
       2020-11-28 11:52:49 +08:00
    根据网上的资料说“数据域采用压缩 BCD 码。”,那十进制的 205 转换后的值好像应该是 05,02,00,00 。如果是数据是有两位小数的,应该是 00,05,02,00 。你找一下 PHP 转换 BCD 码的代码,然后每个加上 0x33 就可以了。
    hxnets
        22
    hxnets  
    OP
       2020-12-03 09:26:04 +08:00
    @zjsxwc 感谢老哥,实测有效,想赠送金币表达感谢,应该怎么操作呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1203 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 23:53 · PVG 07:53 · LAX 15:53 · JFK 18:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.