Python Forum
Unable to bit shift and logical OR bytes and ints?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Unable to bit shift and logical OR bytes and ints?
#1
Python 3.8.2
Windows 10
Powershell

I'm trying to grab a set of 32 bit little-endian pointers from the headers in a set of 256 files, and print them sequentially with line breaks between them.

import sys,glob

def printFileAddr(fileName):
    with open(fileName,"rb") as file:
        file.seek(36,0)
        address = file.read(1)
        address = ((file.read(1) << 8) | address)
        address = ((file.read(1) << 16) | address)
        address = ((file.read(1) << 24) | address)
        print(str(address) + "\n")

for arg in sys.argv[1:]:
    for files in glob.glob(arg):
        printFileAddr(files)
Output
PS C:\Users\pc\Projects\romhack\sagaFrontier\scripts> python .\printArc.py .\M000.ARC         
Traceback (most recent call last):                                                            
  File ".\printArc.py", line 14, in <module>                                                  
    printFileAddr(files)                                                                      
  File ".\printArc.py", line 7, in printFileAddr                                              
    address = ((file.read(1) << 8) | address)                                                 
TypeError: unsupported operand type(s) for <<: 'bytes' and 'int'                              
PS C:\Users\pc\Projects\romhack\sagaFrontier\scripts>                                         
1. Why doesn't Python allow one to bitshift numbers? Why have bitwise operators if you can't use them?

Here's what it prints when I comment out the lines with bit shifting and logical OR.
PS C:\Users\pc\Projects\romhack\sagaFrontier\scripts> python .\printArc.py .\M000.ARC         
b'`'
2. Why is it not printing the numeric value of the byte?
Reply
#2
file.read() returns an object of type 'bytes', one of the fundamental data types of Python that you need to learn. The bytes type is an array of small integers in the range(0, 256). Your file.read(1) are arrays with a single element. Replace this by file.read(1)[0] to access the integer.
>>> b'`'[0]
96
Reply
#3
That did it, thank you.

Here's the final version, with a commented out line for printing in hexadecimal (which is sometimes easier to read).
import sys,glob

def printFileAddr(fileName):
    with open(fileName,"rb") as file:
        file.seek(36,0)
        address = file.read(1)[0]
        address = ((file.read(1)[0] << 8) | address)
        address = ((file.read(1)[0] << 16) | address)
        address = ((file.read(1)[0] << 24) | address)
        print(str(address) + "\n")
        #print(hex(address) + "\n")

for arg in sys.argv[1:]:
    for files in glob.glob(arg):
        printFileAddr(files)
Is there something like the Java Specs but for the various versions of Python?
https://docs.oracle.com/javase/7/docs/api/

It has summaries of all constructors, methods (including parameters and return values), fields, interfaces, and classes.
https://docs.oracle.com/javase/7/docs/ap...yList.html

How do I inspect or determine return types?
Reply
#4
https://docs.python.org/3/
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
You could have used this instead, to handle four bytes at a time
import struct
address = struct.unpack('I', file.read(4))[0]
You could even handle more than four bytes at a time
>>> import struct
>>> s = b'spameggsfoooquxx'
>>> struct.unpack('IIII', s)
(1835102323, 1936156517, 1869573990, 2021160305)
Reply
#6
(Aug-30-2020, 05:14 AM)Gribouillis Wrote: You could have used this instead, to handle four bytes at a time
import struct
address = struct.unpack('I', file.read(4))[0]
You could even handle more than four bytes at a time
>>> import struct
>>> s = b'spameggsfoooquxx'
>>> struct.unpack('IIII', s)
(1835102323, 1936156517, 1869573990, 2021160305)
I believe you but:
  1. I already know bitwise operations.
  2. When I look at this n years from now I want to understand it as fast as possible.
  3. No one knows if your solution will be supported in future versions of Python.
  4. I'm past the age where learning new things that don't have immediate applications, but do have simpler solutions, is fun.
Reply
#7
MysticLord Wrote:No one knows if your solution will be supported in future versions of Python.
Ok, but this solution already worked in Python 1.5.2, released march 22, 2000, more than 20 years ago. The struct module itself is even older, the 'I' format being probably added in python 1.5. My bet is that the struct module will be here for another 20 years.
Reply
#8
Nice thing about struct.pack and unpack is it is very easy to fix bytesex problems and you can read/write arrays and structures.

Since struct is the common way to communicate with C/C++ it is going to be around as long as Python. And it is well documented.

As for readability, the shift code reads easier than this?
def header_address(filename):
    '''Return unsigned int value starting at byte 36 in the file header'''
    with open(filename, "rb") as file:
        file.seek(36, 0)
        return struct.unpack('>I', file.read(4))
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Find a shift between 2 pictures TazFleck 0 1,103 Jan-18-2023, 09:56 PM
Last Post: TazFleck
  Help with Logical error processing List of strings dmc8300 3 1,031 Nov-27-2022, 04:10 PM
Last Post: Larz60+
  [split] why can't i create a list of numbers (ints) with random.randrange() astral_travel 7 1,430 Oct-23-2022, 11:13 PM
Last Post: Pedroski55
  Convert String of an int array to a Numpy array of ints mdsousa 5 5,578 Apr-08-2021, 08:00 PM
Last Post: mdsousa
  Greedy algorithms on logical problems Opensourcehacker 0 1,507 Nov-22-2020, 05:12 PM
Last Post: Opensourcehacker
  List index out of range error when attempting to make a basic shift code djwilson0495 4 2,934 Aug-16-2020, 08:56 PM
Last Post: deanhystad
  Writing a basic shift code djwilson0495 2 2,220 Aug-16-2020, 01:52 PM
Last Post: djwilson0495
  Basic logical errors cpopescu 3 2,011 Jun-03-2020, 11:30 AM
Last Post: menator01
  Python logical operator AND rasec70 4 2,479 May-07-2020, 03:40 PM
Last Post: pyzyx3qwerty
  Pynput doesn't recognize shift button and special characters VirtualDreamer 0 2,983 Jul-17-2019, 11:55 AM
Last Post: VirtualDreamer

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020