鱼C论坛

 找回密码
 立即注册
查看: 777|回复: 26

[已解决]python 字节碰到 的的问题

[复制链接]
发表于 2021-11-15 10:02:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x


我用hex(4565)  ,得到 16进制  11d5    ,但存放的是  d5  11,  也就是高低位交换了,而且python 里面比如  hex(2016 ) 得到是0x7e0  ,高位的07  转成7了  ,这样的,存放到 .cis 文件 中0x7 还能 是07吗?要补码操作吗,高低位交换是分离在合成 ,    根本大神给的方法和我网上查到后,测试结果 发现 代码如下
ybnum = 99
print(hex(ybnum))   # 转换为十六进制
# 数量二个字节高低位交换
data_byte1 = ybnum.to_bytes(length=2, byteorder='little', signed=True)
print(data_byte1)

得到的结果很奇怪:
0x63
b'c\x00'


如果 是4565 这个数就是对,其它的好些个有变。
查到这个to_bytes  是参数范围是0到255  ,我有点不知怎么搞了,请大神帮忙 看下
最佳答案
2021-11-15 15:39:24
你不用管hex的返回值是什么,它的返回值是一个字符串,只是给人看的,如果前缀是0他会将0省去(毕竟只是给人看的),其返回值只能用来参考数据以大端模式时候的大致样子。
关键是to_bytes的返回值,毕竟它返回的字节码是要被你写入文件中的,跟hex没半点关系。
  1. ybnum = 99
  2. # print(hex(ybnum))   # 转换为十六进制
  3. # 数量二个字节高低位交换 x
  4. # 不能理解成高低位交换,只能说是生成小端模式顺序的字节码(byteorder="big"就生成大端模式顺序的)
  5. # 比较一般x86_64的个人PC,数据都是以小端模式储存的,你改变不了它
  6. data_byte1 = ybnum.to_bytes(length=2, byteorder="little", signed=True)
  7. print(data_byte1)

  8. # b"c\x00" 和 b"\x63\x00"是相等的,\x63显示成c只是因为\x63刚好对应c的
  9. # ascii码python将其显示成c给你看(个人认为这点不好,我并不想看\x63是什么字母)
  10. print(data_byte1 == b"\x63\x00")

  11. print((2016).to_bytes(2, "big"))    # 生成大端模式顺序的字节码  b'\x07\xe0'
复制代码



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-15 10:24:27 | 显示全部楼层
本帖最后由 jackz007 于 2021-11-15 10:31 编辑

        看了半天,不知道你究竟想干啥?
        一般的应用不涉及字节顺序问题,除非你有二进制文件需要跨大、小端系统使用。否则,完全没有必要关心字节顺序问题!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-15 10:34:41 | 显示全部楼层
本帖最后由 molinchz 于 2021-11-15 11:07 编辑
jackz007 发表于 2021-11-15 10:24
看了半天,不知道你究竟想干啥?


意思 是这样,要存放的数总共是二个字节 , 10进制转成16进制 到存放 ,转成16进制 后,高低交换存放  ,比如 hex(4565)  ,得到 16进制  11d5 ,这个是二字节,最后交换存放 是01 00  ,如果是一个字节,就不用交换。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-15 10:43:45 | 显示全部楼层
本帖最后由 jackz007 于 2021-11-15 10:44 编辑
molinchz 发表于 2021-11-15 10:34
意思 是这样,要存放的数总共是二个字节 , 10进制转成16进制 到存放 ,转成16进制 后,高低交换存放  , ...


        你这个说法脱离使用场景,大端、小端是针对需要多字节编码的数值型变量而存在的,例如,32位整型数、32位浮点数每个数需要用 4 个字节来表示;64 位整型数、64 位浮点数每个数需要用 8 个字节来表示,这些字节的排列顺序才是大小端体系架构带来的真正区别。单纯讨论字节顺序变换没有任何实际意义。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-15 15:39:24 | 显示全部楼层    本楼为最佳答案   
你不用管hex的返回值是什么,它的返回值是一个字符串,只是给人看的,如果前缀是0他会将0省去(毕竟只是给人看的),其返回值只能用来参考数据以大端模式时候的大致样子。
关键是to_bytes的返回值,毕竟它返回的字节码是要被你写入文件中的,跟hex没半点关系。
  1. ybnum = 99
  2. # print(hex(ybnum))   # 转换为十六进制
  3. # 数量二个字节高低位交换 x
  4. # 不能理解成高低位交换,只能说是生成小端模式顺序的字节码(byteorder="big"就生成大端模式顺序的)
  5. # 比较一般x86_64的个人PC,数据都是以小端模式储存的,你改变不了它
  6. data_byte1 = ybnum.to_bytes(length=2, byteorder="little", signed=True)
  7. print(data_byte1)

  8. # b"c\x00" 和 b"\x63\x00"是相等的,\x63显示成c只是因为\x63刚好对应c的
  9. # ascii码python将其显示成c给你看(个人认为这点不好,我并不想看\x63是什么字母)
  10. print(data_byte1 == b"\x63\x00")

  11. print((2016).to_bytes(2, "big"))    # 生成大端模式顺序的字节码  b'\x07\xe0'
复制代码



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-15 16:23:39 | 显示全部楼层
hrpzcf 发表于 2021-11-15 15:39
你不用管hex的返回值是什么,它的返回值是一个字符串,只是给人看的,如果前缀是0他会将0省去(毕竟只是给人 ...

谢谢,我自己测试 了写入,确实 是这样,返回值什么 不重要,写入的是16进制 的转码,但写入编码 是高低位交换 的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-15 16:34:36 From FishC Mobile | 显示全部楼层
molinchz 发表于 2021-11-15 16:23
谢谢,我自己测试 了写入,确实 是这样,返回值什么 不重要,写入的是16进制 的转码,但写入编码 是高低 ...

写入什么是由你决定的,你to_bytes用的little参数,生成小端模式字节码,当然是高低位相反的,你要用big参数才能生成高低位不相反的字节码。读取你的二进制文件的其他程序也要按大端模式读取才能正确还原数值,否则会出错,你得先了解读取你的文件的程序到底是按大端还是小端读取的,再决定你要不要用大端模式生成字节码并写入文件。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-15 17:05:29 | 显示全部楼层
hrpzcf 发表于 2021-11-15 16:34
写入什么是由你决定的,你to_bytes用的little参数,生成小端模式字节码,当然是高低位相反的,你要用big ...

明白了,谢谢,转得好麻烦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-15 22:36:43 | 显示全部楼层
hrpzcf 发表于 2021-11-15 16:34
写入什么是由你决定的,你to_bytes用的little参数,生成小端模式字节码,当然是高低位相反的,你要用big ...

大神,在问下  1000   这个出来的16进制是  00  00 7A  44    ,这是什么编码 ?  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-15 23:40:15 From FishC Mobile | 显示全部楼层
molinchz 发表于 2021-11-15 22:36
大神,在问下  1000   这个出来的16进制是  00  00 7A  44    ,这是什么编码 ?

你看错了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-16 11:06:31 | 显示全部楼层

1000 的转出来是   00 00 122  68   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-16 15:10:19 | 显示全部楼层
molinchz 发表于 2021-11-16 11:06
1000 的转出来是   00 00 122  68

我忘了附上VBA的代码
H2里面是1000
Public Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) 'EXCEL申明
CopyMemory(EndFile(41), CSng(Range("H2")), 4)      
得到的结果 不是000003e8   而是00007a44

把CSng换成CLng。CSng是转换为单精度数,在内存中其存储格式与长整型是不一样的。而CopyMemory是按地址传递参数的,会将保存单精度数的地址(这里其实就是保存CSng函数返回值的内存地址)传递过去,然后取出这个地址内的4个字节直接复制到你EndFile字节数组的指定位置代表的内存地址,
还有就是,4字节代表的整数存储的顺序是高位在后,复制过去应该是E8 03 00 00,表示的就是3E8这个十六进制数,但现在复制过去的数据表示为整数      就是447A0000,,这怎么来算出这个数呢,最后一步了!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-16 15:52:10 From FishC Mobile | 显示全部楼层
molinchz 发表于 2021-11-16 15:10
我忘了附上VBA的代码
H2里面是1000
Public Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias ...

  1. import struct

  2. f = struct.pack("<f", 1000.0)    # 以浮点型生成字节码(小端)
  3. print("字节码内容:", f)    # 打印字节码的值

  4. for b in f:
  5.     print(b, end="\t")    # 打印字节码的值(以十进制)
  6. print()
  7. for b in f:
  8.     print(r"\x%02x" % b, end="\t") # 打印字节码的值(以十六进制)
复制代码

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-16 15:59:26 From FishC Mobile | 显示全部楼层
@不二如是 大佬帮忙审核一下回复
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-16 16:43:41 | 显示全部楼层
hrpzcf 发表于 2021-11-16 15:59
@不二如是 大佬帮忙审核一下回复

大佬,是不是这样可以解了,
s = float('1000')
print(struct.pack('<f', s).hex())#小端
#输出:00007a44
print(struct.pack('>f', s).hex())#大端
#输出:447a0000
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-16 17:14:48 | 显示全部楼层
molinchz 发表于 2021-11-16 16:43
大佬,是不是这样可以解了,
s = float('1000')
print(struct.pack('f', s).hex())#大端

是的,我上一条回复跟这差不多但被审核了,让大佬审核回复但是大佬会错意选了最佳
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-16 20:49:34 | 显示全部楼层
hrpzcf 发表于 2021-11-16 17:14
是的,我上一条回复跟这差不多但被审核了,让大佬审核回复但是大佬会错意选了最佳

float_to_hex = struct.pack('<f', s)#小端
data_byte1 = ybnum.to_bytes(length=2, byteorder='little', signed=True)   
大佬,这个s  和ybnum   怎样写成变量的模式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 09:26:46 From FishC Mobile | 显示全部楼层
molinchz 发表于 2021-11-16 20:49
float_to_hex = struct.pack('

你现在写的不就是变量吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 16:35:52 | 显示全部楼层
hrpzcf 发表于 2021-11-17 09:26
你现在写的不就是变量吗

for com_num in range(393000, 394000, 1):
    with open(os.path.join(lc_path, f"{com_num}.cis"), "wb") as cisf:   

老师,我增加一个变量假如是 bklist=321  ,我只要计数这321次,怎样修改代码 ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 16:45:31 | 显示全部楼层
molinchz 发表于 2021-11-17 16:35
for com_num in range(393000, 394000, 1):
    with open(os.path.join(lc_path, f"{com_num}.cis"), " ...

循环外面把它初始化为0,循环里一直 +1 就行了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-6 03:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表