Created
January 14, 2019 00:35
-
-
Save chaddotson/debde2f9ee7783387fa6713b8a1048fa to your computer and use it in GitHub Desktop.
Working with binary in Python 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from ctypes import c_int, Structure | |
from inspect import getsource | |
from struct import pack_into, unpack_from | |
# Create 2 buffers, one smaller than the other for | |
# demonstration purposes. | |
buff1 = bytearray(64) | |
buff2 = bytearray(32) | |
# first we'll use the struct package to initalize the arrays. | |
# initialize buff1 with 32 integers. | |
pack_into('I' * 16, buff1, 0, *range(0, 16)) | |
print('Buffer 1:', unpack_from('I' * 16, buff1, 0)) | |
# copy part of buff1 into buff2, since we're using | |
# bytearrays, this should be equivalent to a memcpy | |
buff2[:] = buff1[:32] | |
# test it out, did we copy 32 bytes from buff1 into buff2? | |
print('Buffer 2:', unpack_from('I' * 8, buff2, 0)) | |
print() | |
# We can also use the ctypes package to access the buffers | |
# We can access it peice-meal like this. Note that this | |
# copies the buffer, if we didn't want a copy. from_buffer | |
# is the function we would use. | |
x = c_int.from_buffer_copy(buff2, 8) | |
y = c_int.from_buffer_copy(buff2, 12) | |
print(f'x, y as 2 standalone c_ints: {x.value}, {y.value}') | |
print() | |
# You can also create C Structures to access the data | |
class Point(Structure): | |
_fields_ = [ | |
('x', c_int), | |
('y', c_int) | |
] | |
print('Define a ctypes structure:') | |
print(getsource(Point)) | |
p1 = Point.from_buffer_copy(buff2, 8) | |
print(f'x, y as elements of a ctype structure (copied): {p1.x}, {p1.y}') | |
# note that since this is a copy any manipulation doesn't | |
# effect the buffer. | |
p1.x, p1.y = 50, 51 | |
print(f'p1.x, p1.y set to: {p1.x}, {p1.y}') | |
print('Show buffer2 is unchanged:', unpack_from('I' * 8, buff2, 0)) | |
print() | |
# so, if we wanted to manipulate the buffer using the structure | |
print(f'x, y as elements of a ctype structure (not copied): {p1.x}, {p1.y}') | |
p2 = Point.from_buffer(buff2, 8) | |
p2.x, p2.y = 100, 101 | |
print(f'p2.x, p2.y set to: {p2.x}, {p2.y}') | |
# see that the 3rd and 4th element now been changed. | |
print('Show buffer2 is changed:', unpack_from('I' * 8, buff2, 0)) | |
print() | |
# finally note that the original buffer is unchanged. | |
print('Show buffer1 unchanged:', unpack_from('I' * 16, buff1, 0)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment