简体   繁体   English

将十六进制值写入文件Python

[英]Writing hex value into file Python

What I am really doing is creating a BMP file from JPEG using python and it's got some header data which contains info like size, height or width of the image, so basically I want to read a JPEG file, gets it width and height, calculate the new size of a BMP file and store it in the header. 我真正在做的是使用python从JPEG创建BMP文件,并且其中包含一些标头数据,其中包含诸如图像的大小,高度或宽度之类的信息,因此基本上我想读取JPEG文件,获取其宽度和高度,然后进行计算BMP文件的新大小并将其存储在标题中。

Let's say the new size of the BMP file is 40000 bytes whose hex value is 0x9c40 , now as there is 4 byte space to save this in the header, we can write it as 0x00009c40 . 假设BMP文件的新大小为40000个字节,其十六进制值为0x9c40 ,由于头中有4个字节的空间来保存它,我们可以将其写为0x00009c40 In BMP header data, LSB is written first and then MSB so I have to write, 0x409c0000 in the file. 在BMP标头数据中,首先写入LSB,然后写入MSB,因此我必须在文件中写入0x409c0000

My Problems:- 我的问题:

  1. I was able to do this in C but I am totally lost how to do so in Python. 我能够用C语言做到这一点,但我完全不知道如何使用Python做到这一点。

    For example, if I have i=40000 , and by using str=hex(i)[2:] I got the hex value, now by some coding I was able to add the extra zeros and then reverse the code. 例如,如果我有i=40000 ,并且通过使用str=hex(i)[2:]我得到了十六进制值,现在通过某种编码,我能够添加额外的零,然后反转代码。 Now how to write this '409c0000' data in the file as hex? 现在如何将此'409c0000'数据写入十六进制文件中?

  2. The header size is 54 bytes for BMP file, so is there is another way to just store the data in a string like str='00ffcf4f...' (upto 54 bytes) and just convert the whole str at once as hex and write it to file? BMP文件的标头大小为54字节,因此还有另一种方法可以将数据存储在字符串中,例如str='00ffcf4f...'str='00ffcf4f...' 54个字节),然后一次将整个str转换为十六进制并写入要归档吗?

  3. My friend told me to use unhexlify from binascii , by doing unhexlify('fffcff') I get '\\xff\\xfc\\xff' which is what I want but when I try unhexlify('3000') I get '0\\x00'` which is not what I want. 我的朋友告诉我使用unhexlifybinascii ,通过执行unhexlify('fffcff')得到'\\xff\\xfc\\xff' ,这是我想要的,但是当我尝试unhexlify('3000')得到'0 \\ x00' `这不是我想要的。 It is same for any value containing 3, 4, 5, 6 or 7. Is it the right way to do this? 包含3、4、5、6或7的任何值都相同。这是正确的方法吗?

You are not writing hex, you are writing binary data. 您不是在写十六进制,而是在写二进制数据。 Hexadecimal is a helpful notation when dealing with binary data, but don't confuse the notation with the value. 在处理二进制数据时,十六进制是一种有用的表示法 ,但不要将其与值混淆。

Use the struct module to pack integer data into binary structures, the same way C would. 使用struct模块将整数数据打包为二进制结构,就像C一样。

binascii.unhexlify also is a good choice, provided you already have the data in a string using hex notation. binascii.unhexlify也是一个不错的选择,前提是您已经使用十六进制表示法将数据存储在字符串中。 The output is correct , but the binary representation only uses hex escapes for bytes outside the printable ASCII range. 输出是正确的 ,但是二进制表示形式仅对可打印ASCII范围之外的字节使用十六进制转义。

Thus fffcff does correctly becomes \\xff\\xfc\\xff , representing 3 bytes in hex escape notation, and 3000 is \\x30\\x00 , but \\x30 is the '0' character in ASCII, so the Python representation for that byte simply uses that ASCII character, as that is the most common way to interpret bytes. 因此fffcff确实正确地变成\\xff\\xfc\\xff ,以十六进制转义表示3字节,而3000\\x30\\x00 ,但是\\x30是ASCII中的'0'字符,因此该字节的Python表示形式仅使用了ASCII字符,因为这是解释字节的最常用方法。

Packing the integer value 40000 using struct.pack() as an unsigned integer (little endian) then becomes: 使用struct.pack()将整数值40000 struct.pack()为无符号整数(小端),然后变为:

>>> import struct
>>> struct.pack('<I', 40000)
'@\x9c\x00\x00'

where the 40 byte is represented by the ASCII character for that byte, the @ glyph. 其中40个字节由该字节的ASCII字符@字形表示。

If this is confusing, you can always create a new hex representation by going the other way and use 0 binascii.hexlify() function]( https://docs.python.org/2/library/binascii.html#binascii.hexlify ) to create a hexadecimal representation for yourself, just to debug the output: 如果这令人困惑,则始终可以通过另一种方式创建新的十六进制表示形式,并使用0 binascii.hexlify()函数]( https://docs.python.org/2/library/binascii.html#binascii.hexlify )为您自己创建一个十六进制表示形式,仅用于调试输出:

>>> import binascii
>>> binascii.hexlify(struct.pack('<I', 40000))
'409c0000'

and you'll see that the @ byte is still the right hex value. 并且您会看到@字节仍然是正确的十六进制值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM