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
  Greedy algorithms on logical problems Opensourcehacker 0 427 Nov-22-2020, 05:12 PM
Last Post: Opensourcehacker
  Writing a basic shift code djwilson0495 2 733 Aug-16-2020, 01:52 PM
Last Post: djwilson0495
  Basic logical errors cpopescu 3 748 Jun-03-2020, 11:30 AM
Last Post: menator01
  Python logical operator AND rasec70 4 1,011 May-07-2020, 03:40 PM
Last Post: pyzyx3qwerty
  Pynput doesn't recognize shift button and special characters VirtualDreamer 0 1,504 Jul-17-2019, 11:55 AM
Last Post: VirtualDreamer
  Redefine __add__ for ints ihf 4 1,511 Jun-01-2019, 06:29 PM
Last Post: ihf
  parsing logical expression with pyparsing palo173 2 2,816 May-13-2019, 09:22 AM
Last Post: palo173
  replace bytes with other byte or bytes BigOldArt 1 4,129 Feb-02-2019, 11:00 PM
Last Post: snippsat
Bug Random Ints to Str Problem BIGPESH 2 1,209 Aug-18-2018, 12:44 PM
Last Post: BIGPESH
  Paramter lists when shift+tab doesn't work sobrio1 0 1,991 Oct-15-2017, 03:41 PM
Last Post: sobrio1

Forum Jump:

User Panel Messages

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