Get nth byte of integer - python

I have the following integer:
target = 0xd386d209
print hex(target)
How can I print the nth byte of this integer? For example, expected output for the first byte would be:
0x09

You can do this with the help of bit manipulation. Create a bit mask for an entire byte, then bitshift that mask the number of bytes you'd like. Mask out the byte using binary AND and finally bitshift back the result to the first position:
target = 0xd386d209
byte_index = 0
mask = 0xFF << (8 * byte_index)
print hex((target & mask) >> (8 * byte_index))
You can simplify it a little bit by shifting the input number first. Then you don't need to bitshift the mask value at all:
target = 0xd386d209
byte_index = 0
mask = 0xFF
print hex((target >> (8 * byte_index)) & mask)

def byte(number, i):
return (number & (0xff << (i * 8))) >> (i * 8)

>>> def print_n_byte(target, n):
... return hex((target&(0xFF<<(8*n)))>>(8*n))
...
>>> print_n_byte(0xd386d209, 0)
'0x9L'
>>> print_n_byte(0xd386d209, 1)
'0xd2L'
>>> print_n_byte(0xd386d209, 2)
'0x86L'

This only involves some simple binary operation.
>>> target = 0xd386d209
>>> b = 1
>>> hex((target & (0xff << b * 8)) >> b * 8)
'0x9'
>>> hex((target & (0xff << b * 8)) >> b * 8)
'0xd2'

Related

Cycle a binary number in python

Is there a function that cycle a binary number? for exemple:
100010001000 turns 010001000100
and it turns 001000100010 then 000100010001 and then 100010001000 so on so forth
If 100010001000 is a string, then it is a sequence in Python.
So, you can use the itertools package which contains a cycle function.
This function can iterate your binary string in cycle:
>>> n = "100010001000"
>>> c = itertools.cycle(n)
>>> next(c)
'1'
>>> next(c)
'0'
>>> next(c)
'0'
>>> next(c)
'0'
>>> next(c)
'1'
...
You can use this function to shift the digits:
>>> c = itertools.cycle(n)
>>> next(c)
'1'
>>> "".join(next(c) for _ in range(len(n)))
'000100010001'
If you repeat the last two operations, you get the cycle (but in the other way).
You can also use slice concatenations, for instance:
>>> n = "100010001000"
>>> n = n[-1:] + n[0:-1]
>>> n
'010001000100'
>>> n = n[-1:] + n[0:-1]
>>> n
'001000100010'
>>> n = n[-1:] + n[0:-1]
>>> n
'000100010001'
If your number is an integer, you can use binary operators, like >>, <<, & and |.
To do so, you need to know the length of your binary integer, here it has 12 digits.
Just calculate a mask m with all digits set to 1. And do the rotating:
>>> m = int("111111111111", 2)
>>> n = int("100010001000", 2)
>>> bin(n)
'0b100010001000'
>>> n = (n >> 1) | (n << 11) & m
>>> bin(n)
'0b10001000100'
>>> n = (n >> 1) | (n << 11) & m
>>> bin(n)
'0b1000100010'
>>> n = (n >> 1) | (n << 11) & m
>>> bin(n)
'0b100010001'
>>> n = (n >> 1) | (n << 11) & m
>>> bin(n)
'0b100010001000'
This is a very good source for rotational bit shifts in Python:
https://www.falatic.com/index.php/108/python-and-bitwise-rotation
I thought there was a native function, but nevermind, i made this loosey goosey function that works for me
def cycle(n):
return n[-1] + n[:-1]

Python working with bits

I want to do a bit operation, and need some help:
I have a word of 16 bit and want to split it into two, reverse each and then join them again.
Example if i have 0b11000011
First I divide it into 0b1100 and 0b0011
Then i reverse both getting 0b0011 and 0b1100
And finally rejoin them getting 0b00111100
Thanks!
Here's one way to do it:
def rev(n):
res = 0
mask = 0x01
while mask <= 0x80:
res <<= 1
res |= bool(n & mask)
mask <<= 1
return res
x = 0b1100000110000011
x = (rev(x >> 8) << 8) | rev(x & 0xFF)
print bin(x) # 0b1000001111000001
Note that the method above operates on words, not bytes as example in the question.
here are some basic operations you can try, and you can concatenate results after splitting your string in two and reversing it
a = "0b11000011" #make a string
b = a[:6] #get first 5 chars
c = a[::-1] # invert the string

Why should I be failing this simple python algorithm?

I have an algorithm that I want to write in python and analyze it. I think I wrote it well, but my output doesn't match what the given output should be.
given algorithm;
Input{inStr: a binary string of bytes}
Output{outHash: 32-bit hashcode for the inStr in a series of hex values}
Mask: 0x3FFFFFFF
outHash: 0
for byte in input
intermediate_value = ((byte XOR 0xCC) Left Shift 24) OR
((byte XOR 0x33) Left Shift 16) OR
((byte XOR 0xAA) Left Shift 8) OR
(byte XOR 0x55)
outHash =(outHash AND Mask) + (intermediate_value AND Mask)
return outHash
My algorithm version in python is;
Input = "Hello world!"
Mask = 0x3FFFFFFF
outHash = 0
for byte in Input:
intermediate_value = ((ord(byte) ^ 0xCC) << 24) or ((ord(byte) ^ 0x33) << 16) or ((ord(byte) ^ 0xAA) << 8) or (ord(byte) ^ 0x55)
outHash =(outHash & Mask) + (intermediate_value & Mask)
print outHash
# use %x to print result in hex
print '%x'%outHash
For input "Hello world!", I should see output as 0x50b027cf, but my output is too different, it looks like;
1291845632
4d000000
OR must be bitwise OR operator (|).

How can i add bytearrays In python?

I'm new in python.
I have a bytearray of shellcode:
a=bytearray('\x31\xcb\x50\x69').
What i have to do is to +1 to every each of them to have this result:
bytearray('\x32\xcc\x51\x6a').
Any good ideas how I can achieve these in python?
Thank you and best regards,
>>> a=bytearray('\x31\xcb\x50\x69')
>>> a
bytearray(b'1\xcbPi') # repr uses a different but equivalent representation
>>> bytearray(x + 1 for x in a)
bytearray(b'2\xccQj')
You will need to consider what it means to +1 to 0xff
for example
bytearray((x + 1) % 0xff for x in a) # wrap around
or
bytearray(min(x + 1), 0xff) for x in a) # limit to 0xff
It's probably faster to use the translate method if you are doing a few of these
>>> trans_table = bytearray(range(1, 256)) + '\x00'
>>> a.translate(trans_table)
bytearray(b'2\xccQj')
If you want to print the arrays to look like that, use the repr() function
>>> print a
1�Pi
>>> print repr(a)
bytearray(b'1\xcbPi')
a = bytearray('\x31\xcb\x50\x69')
a = bytearray(b + 1 if b < 255 else 0 for b in a)
Change the 0 to 255 if you want to clip the value rather than wrappping back around to zero.
You can do as follows:
a=bytearray('\x31\xcb\x50\x69')
new_a = bytearray(b + 1 for b in a)
for b in new_a:
print('{:02x}'.format(b))
Outputs:
32
cc
51
6a

Concatenate two 32 bit int to get a 64 bit long in Python

I want to generate 64 bits long int to serve as unique ID's for documents.
One idea is to combine the user's ID, which is a 32 bit int, with the Unix timestamp, which is another 32 bits int, to form an unique 64 bits long integer.
A scaled-down example would be:
Combine two 4-bit numbers 0010 and 0101 to form the 8-bit number 00100101.
Does this scheme make sense?
If it does, how do I do the "concatenation" of numbers in Python?
Left shift the first number by the number of bits in the second number, then add (or bitwise OR - replace + with | in the following examples) the second number.
result = (user_id << 32) + timestamp
With respect to your scaled-down example,
>>> x = 0b0010
>>> y = 0b0101
>>> (x << 4) + y
37
>>> 0b00100101
37
>>>
foo = <some int>
bar = <some int>
foobar = (foo << 32) + bar
This should do it:
(x << 32) + y
For the next guy (which was me in this case was me). Here is one way to do it in general (for the scaled down example):
def combineBytes(*args):
"""
given the bytes of a multi byte number combine into one
pass them in least to most significant
"""
ans = 0
for i, val in enumerate(args):
ans += (val << i*4)
return ans
for other sizes change the 4 to a 32 or whatever.
>>> bin(combineBytes(0b0101, 0b0010))
'0b100101'
None of the answers before this cover both merging and splitting the numbers. Splitting can be as much a necessity as merging.
NUM_BITS_PER_INT = 4 # Replace with 32, 48, 64, etc. as needed.
MAXINT = (1 << NUM_BITS_PER_INT) - 1
def merge(a, b):
c = (a << NUM_BITS_PER_INT) | b
return c
def split(c):
a = (c >> NUM_BITS_PER_INT) & MAXINT
b = c & MAXINT
return a, b
# Test
EXPECTED_MAX_NUM_BITS = NUM_BITS_PER_INT * 2
for a in range(MAXINT + 1):
for b in range(MAXINT + 1):
c = merge(a, b)
assert c.bit_length() <= EXPECTED_MAX_NUM_BITS
assert (a, b) == split(c)

Categories

Resources