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

2020-11-27 16:06:31 +08:00
 hxnets

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

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

2440 次点击
所在节点    PHP
22 条回复
hxnets
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
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
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
2020-11-27 17:14:06 +08:00
为何要加 0x33,为何要保持 8 位。。
说实话看了问题和下面的回复,一脸懵逼,踏入了未知领域
zjsxwc
2020-11-27 17:36:28 +08:00
3689348814741910500 这个值可能不对,因为我是网页计算器算的,但是由于 js 天生不支持 64 位整数所以网页计算器算了这个错误值,你直接用 0x33 33 33 33 33 33 33 33 代替就好了。
hxnets
2020-11-27 17:42:20 +08:00
@zjsxwc 首先感谢老哥的回复,我这边现在是处理 dlt645 协议,协议要求要对数据域的每字节+33,当充值此处小的时候没关系,但是当充值此处 200 以上的时候,数据会进位,协议要求的字节长度是 8 位,这时候产生的数据是 9 位,导致指令出错,现在应该是要对数据取低位。

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

所以 如果有一个字符串 我应该怎么取它的低 8 位?
si
2020-11-27 17:59:00 +08:00
不太明白“想保持这个数据长度为 8 位”是什么意思,建议直接给出预计结果是什么,比如 00,33,33,33 。或者直接贴文档说明。
zjsxwc
2020-11-27 18:12:20 +08:00
@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
2020-11-27 18:24:07 +08:00
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
2020-11-27 18:32:43 +08:00
@zjsxwc 你说的这些知识 属于哪块领域啊?
zjsxwc
2020-11-27 18:43:05 +08:00
@xxbutoo 计算机原理啊
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
2020-11-27 23:40:31 +08:00
C#语言,你处理的是数据域,应该可以它山之石 https://www.cnblogs.com/myzony/p/10897895.html
947211232
2020-11-28 00:12:09 +08:00
hxnets
2020-11-28 11:24:48 +08:00
@si 协议要求的比如说充值数量和充值读书的字节长度是 8 位,其实这个问题就是 数值进位后 的问题,应该取值的低字节位
hxnets
2020-11-28 11:25:53 +08:00
@947211232 感谢老哥 这个我也有参考,问题是 我看了现在的大部分的相关系统 都没有对 进位的情况作处理,这个问题要充值度数很大的情况下才会出现
hxnets
2020-11-28 11:26:44 +08:00
@zjsxwc 啊。。。这 我试试看
hxnets
2020-11-28 11:28:25 +08:00
@ETiV 数据域的总长度是有要求的,另外就是数据要转换成 二进制发送,使用 hextobin 的时候 如果字符串是 奇数位就会出错
hxnets
2020-11-28 11:33:32 +08:00
@zjsxwc 那这样的话,充值次数的值就是 38 ?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/729910

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX