Skip to content

Instantly share code, notes, and snippets.

@FFY00
Created July 24, 2020 15:20
Show Gist options
  • Save FFY00/a9ec13d695aa6f8b28d91f31b17cde32 to your computer and use it in GitHub Desktop.
Save FFY00/a9ec13d695aa6f8b28d91f31b17cde32 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
def shift(buf, offset, length):
assert length > 0
left_extra = offset % 8
right_extra = 8 - (offset + length) % 8
start_offset = offset // 8
end_offset = (offset + length - 1) // 8
byte_length = (length - 1) // 8 + 1
assert end_offset < len(buf)
shifted = [0] * byte_length
if right_extra == 8:
right_extra = 0
i = end_offset
shifted_offset = byte_length - 1
while shifted_offset >= 0:
shifted[shifted_offset] = buf[i] >> right_extra
if i - start_offset >= 0:
shifted[shifted_offset] |= (buf[i - 1] & (0xff >> (8 - right_extra))) << (8 - right_extra)
shifted_offset -= 1
i -= 1
shifted[0] &= 0xff >> ((left_extra + right_extra) % 8)
assert len(shifted) == byte_length
return shifted
assert shift([0xff, 0xff, 0xff], 7, 10) == [0b00000011, 0b11111111]
assert shift([0xff, 0x00, 0xff], 7, 10) == [0b00000010, 0b00000001]
assert shift([0xff, 0x00, 0xff], 4, 16) == [0b11110000, 0b00001111]
assert shift([0xff, 0xff], 2, 12) == [0b00001111, 0b11111111]
assert shift([0x00], 0, 1) == [0b00000000]
assert shift([0x00], 0, 8) == [0b00000000]
assert shift([0xff], 0, 1) == [0b00000001]
assert shift([0xff], 0, 4) == [0b00001111]
assert shift([0xff], 0, 8) == [0b11111111]
assert shift([0b10111111], 0, 3) == [0b00000101]
assert shift([0b11101111], 2, 3) == [0b00000101]
assert shift([0b11111011], 4, 3) == [0b00000101]
assert shift([0xff, 0xff], 0, 8) == [0b11111111]
assert shift([0xff, 0xff], 0, 12) == [0b1111, 0b11111111]
assert shift([0xaa, 0xbb, 0xcc], 0, 8) == [0xaa]
assert shift([0xaa, 0xbb, 0xcc], 8, 8) == [0xbb]
assert shift([0xaa, 0xbb, 0xcc], 16, 8) == [0xcc]
assert shift([0xaa, 0xbb, 0xcc], 4, 8) == [0xab]
assert shift([0xaa, 0xbb, 0xcc], 12, 8) == [0xbc]
assert shift([0xab, 0xcd, 0xef], 0, 4) == [0xa]
assert shift([0xab, 0xcd, 0xef], 4, 4) == [0xb]
assert shift([0xab, 0xcd, 0xef], 8, 4) == [0xc]
assert shift([0xab, 0xcd, 0xef], 12, 4) == [0xd]
assert shift([0xab, 0xcd, 0xef], 16, 4) == [0xe]
assert shift([0xab, 0xcd, 0xef], 20, 4) == [0xf]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment