Created
July 24, 2020 15:20
-
-
Save FFY00/a9ec13d695aa6f8b28d91f31b17cde32 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/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