Skip to content

Instantly share code, notes, and snippets.

@chaddotson
Created January 14, 2019 00:35
Show Gist options
  • Save chaddotson/debde2f9ee7783387fa6713b8a1048fa to your computer and use it in GitHub Desktop.
Save chaddotson/debde2f9ee7783387fa6713b8a1048fa to your computer and use it in GitHub Desktop.
Working with binary in Python 3
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