简体   繁体   English

Python,如何将32位整数放入字节数组中

[英]Python, how to put 32-bit integer into byte array

I usually perform things like this in C++, but I'm using python to write a quick script and I've run into a wall. 我通常在C ++中执行这样的操作,但我正在使用python编写一个快速脚本而且我遇到了问题。

If I have a binary list (or whatever python stores the result of an "fread" in). 如果我有一个二进制列表(或任何python存储“fread”的结果)。 I can access the individual bytes in it with: buffer[0], buffer[1], etc. 我可以使用:buffer [0],buffer [1]等访问其中的各个字节。

I need to change the bytes [8-11] to hold a new 32-bit file-size (read: there's already a filesize there, I need to update it). 我需要更改字节[8-11]以保存新的32位文件大小(读取:那里已有文件大小,我需要更新它)。 In C++ I would just get a pointer to the location and cast it to store the integer, but with python I suddenly realized I have no idea how to do something like this. 在C ++中,我只是得到一个指向该位置的指针并将其转换为存储整数,但是使用python我突然意识到我不知道如何做这样的事情。

How can I update 4 bytes in my buffer at a specific location to hold the value of an integer in python? 如何在特定位置更新缓冲区中的4个字节以保存python中的整数值?

EDIT 编辑

I'm going to add more because I can't seem to figure it out from the solutions (though I can see they're on the right track). 我将添加更多,因为我似乎无法从解决方案中找到它(虽然我可以看到它们在正确的轨道上)。

First of all, I'm on python 2.4 (and can't upgrade, big corporation servers) - so that apparently limits my options. 首先,我在python 2.4(并且无法升级,大公司服务器) - 所以这显然限制了我的选择。 Sorry for not mentioning that earlier, I wasn't aware it had so many less features. 很抱歉没有提及,我不知道它有这么多的功能。

Secondly, let's make this ultra-simple. 其次,让我们做到这一点非常简单。

Lets say I have a binary file named 'myfile.binary' with the five-byte contents '4C53535353' in hex - this equates to the ascii representations for letters "L and 4xS" being alone in the file. 假设我有一个名为'myfile.binary'的二进制文件,其中包含十六进制的五字节内容'4C53535353' - 这相当于文件中单独的字母“L和4xS”的ascii表示。

If I do: 如果我做:

f = open('myfile.binary', 'rb')
contents = f.read(5)

contents should (from Sven Marnach's answer) hold a five-byte immutable string. 内容应该(来自Sven Marnach的答案)保存一个五字节的不可变字符串。

Using Python 2.4 facilities only, how could I change the 4 S's held in 'contents' to an arbitrary integer value? 仅使用Python 2.4工具,如何将'contents'中的4 S更改为任意整数值? Ie give me a line of code that can make byte indices contents [1-4] contain the 32-bit integer 'myint' with value 12345678910. 即给我一行代码,可以使字节索引内容[1-4]包含值为12345678910的32位整数'myint'。

What you need is this function: 你需要的是这个功能:

struct.pack_into(fmt, buffer, offset, v1, v2, ...)

It's documented at http://docs.python.org/library/struct.html near the top. 它位于顶部附近的http://docs.python.org/library/struct.html上。

Example code: 示例代码:

import struct
import ctypes

data=ctypes.create_string_buffer(10)
struct.pack_into(">i", data, 5, 0x12345678)
print list(data)

Similar posting: Python: How to pack different types of data into a string buffer using struct.pack_into 类似的帖子: Python:如何使用struct.pack_into将不同类型的数据打包到字符串缓冲区中

EDIT: Added a Python 2.4 compatible example: 编辑:添加了Python 2.4兼容的示例:

import struct

f=open('myfile.binary', 'rb')
contents=f.read(5)
data=list(contents)
data[0:4]=struct.pack(">i", 0x12345678)
print data

Have a look at Struct module. 看看Struct模块。 You need pack function. 你需要pack功能。

EDIT: 编辑:

The code: 编码:

import struct

s = "LSSSS" # your string
s = s[0] + struct.pack('<I', 1234567891) # note "shorter" constant than in your example
print s

Output: 输出:

L╙☻ЦI

struct.pack should be available in Python2.4. struct.pack应该在Python2.4中可用。

Your number "12345678910" cannot be packed into 4 bytes, I shortened it a bit. 您的号码“12345678910”无法打包成4个字节,我将其缩短了一点。

The result of file.read() is a string in Python, and it is immutable. file.read()的结果是Python中的一个字符串,它是不可变的。 Depending on the context of the task you are trying to accomplish, there are different solutions to the problem. 根据您要完成的任务的上下文,可以使用不同的解决方案。

One is using the array module : Read the file directly as an array of 32-bit integers. 一种是使用array模块 :直接读取文件为32位整数数组。 You can modify this array and write it back to the file. 您可以修改此数组并将其写回文件。

with open("filename") as f:
    f.seek(0, 2)
    size = f.tell()
    f.seek(0)
    data = array.array("i")
    assert data.itemsize == 4
    data.fromfile(f, size // 4)
data[2] = new_value
# use data.tofile(g) to write the data back to a new file g

You could install the numpy module, which is often used for scientific computing. 您可以安装numpy模块,该模块通常用于科学计算。

read_data = numpy.fromfile(file=id, dtype=numpy.uint32) read_data = numpy.fromfile(file = id,dtype = numpy.uint32)

Then access the data at the desired location and make your changes. 然后访问所需位置的数据并进行更改。

The following is just a demonstration for you to understand what really happens when the four bytes are converted into an integer. 以下只是一个演示,让您了解将四个字节转换为整数时实际发生的情况。 Suppose you have a number: 15213 假设你有一个数字:15213

Decimal: 15213
Binary: 0011 1011 0110 1101
Hex: 3 B 6 D

On little-endian systems (ie x86 machines), this number can be represented using a length-4 bytearray as: b"\\x6d\\x3b\\x00\\x00" or b"m;\\x00\\x00" when you print it on the screen, to convert the four bytes into an integer, we simply do a bit of base conversion, which in this case, is: 在little-endian系统(即x86机器)上,这个数字可以使用长度为4字节的数据表示为: b"\\x6d\\x3b\\x00\\x00"b"m;\\x00\\x00"当你打印它时在屏幕上,要将四个字节转换为整数,我们只需进行一些基本转换,在这种情况下,它是:

sum(n*(256**i) for i,n in enumerate(b"\x6d\x3b\x00\x00"))

This gives you the result: 15213 这给你的结果:15213

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

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