Bit shifting a file

Apr 30, 2011 21 Replies

Here's another one of my not quite electronics questions. I know. But it's also pretty low-level, software gurus don't deal in bit shifting too much anymore. Here's the situation. Got a binary file. The bytes are not bit aligned. It is exactly 1M (1024 x 1024) bytes long. Is there a software or a decent algorithm that can do an 8388608 bit shift? Anyone ever have to deal with this? I can try to whip up some Python code but there might be something out there already. Maybe some obscure combo of grungy old unix tools? Yes, I know that the file will be one byte longer after the operation. That's cool. APL? GNU Octave? Maybe Python itself can >> a file handle? (LOL)


What kind of software gurus are you talking about?

#define 1M 1048576

int i; char c, buf[1M];

leftshift() { for(i=3D0; i Anyone ever have to deal with this? I can try to whip up some Python

The ones that don't answer... The same ones that don't respond when a web server doesn't work, for example.

LOL... Don't think so, but thanks! Here's a clue as to what I'm doing F628

I suspect you mean "that will shift 8388608 bits {left|right} by n bits."

I'd really start with 'C' for bit bashing.

-- Les Cargill

This sounds far too much like a basic computer science homework exercise to deserve an answer.

Yes. There are even languages where you can read in a packed array of bits and have the compiler generate optimised code to do it. For a small file size like 1MB it isn't worth the effort of doing anything other than read shift write. If it was a 1TB file then you would have to think a lot more carefully about shifting blocks of it about.

I take it then that you do not want a cyclic shift as that would not change the file length. As far as interpretation of the file contents is concerned you only need to shift between 1 and 7 bits to get it byte aligned. The origin will be in the wrong place but that is easy.

Don't expect anyone to do your homework on Usenet.

Regards, Martin Brown

So you want him to go to your house and type it in for you? You asked for an algorithm, got good code, and it's a joke to you?

I'm never going to grow up.

If you understand the AH, AL, and AX registers, doing it in assembly language would be almost trivial.

Good Luck! Rich

Look. You never suddenly have to work on something slightly outside your field ? I *know* WHAT I want, I just don't know the specifics. What good code? Where does it read in a binary file? I'd rather keep learning more Python, than taking on C and then being half-assed in two languages. I'd rather keep learning one language, thanks.

Here's the process

1) OK, get some tutorials on Python and reading files.

2) Oh, look, it's something like file =3D open(name, mode)

3) Great! But it doesn't work! Here we go again with the obscure knowledge everyone assumes even total noobs knows. I used the "os" module to ask for the file separator. It tells me "\" since I'm in windows. Eventually I stumble on the fact that even on windows it wants forward slashes. This makes sense? How? So after using "C:/temp.bin" as the name string, it works! Wow! I'm a genius!

4) So I'm using a binary file, remember? So I start reading a byte .... OK, does it have a pointer somewhere where it remembers how many bytes I've read or does it just return a number of bytes from the start every time? Where does it say that? Do I keep typing away or find out? Off to more wild goose chases on Google.

5) Never mind that. I want an INT so I can do shifts, right? Turns out Python always reads a file as a string characters even if the "mode" has a b for binary! Not too bad, I just toss the character to int(), right?

6) Doesn't work! It reads in a character at a time, when it sees a non printable one it becomes a 4 character hex string like this '\x7E'.... Um, now what?

7) Keep googling. And where *is* that pointer I was curious about anyways?

8) Oh, finally here's some info. You import ANOTHER bundle of fun called struct.

9) This finally lets you read a file and returns an int, but it needs format codes. OK, they give you an example for 2 byte reads.... What about single byte reads? Um, where does it say what the format code is for that? Naturally, they are all completely different from any other format codes out there.

So, you think I enjoy this? If it's so simple and basic computer science, how come my only searches on bit shifting a file return ... my post?

You like this kind of circular merry-go-round with half-assed explanations?

OK, then try to install paramiko for python in windows. Go ahead, I'll wait here.

And homework? Really? Check your calendar. It's more likely finals, and there are no comp-sci courses for summer semesters.

Besides, my gut weighs more than the average student, I'm way too old for this stuff. Getting VERY impatient.

(Oh, and I took C over 15 years ago. I was top of my class. I just never worked in software again.)

go to your house and type it in for you? You asked

read(fd, buf, 1M);

next question: how do you open a file?

Sad, so sad with the educational system.

I am not sure what you are trying to do.

If you want to shift a complete file say 98765 bits to the left, all you have to do is to perform a 5 bit left shift and then do a byte copy with 12345 byte offset (8x12345+5=98765).

For best performance on some x86 processor with 4096 virtual memory pages, three page copy offset with 57 byte offset and 5 bit byte offset should do the trick ((3x4096+57)x8+5=98765).

I'm trying to imagine a byte that isn't bit-aligned. Are there a fractional number of bits in each byte?

The length of the file is immaterial to the algorithm.

linnix demonstrated one implementation of the general approach, albeit with some (intentional? probably) errors that won't let the snippet be just dropped in.

Although, taken literally, given that one would typically call the operation transforming {0x01} to {0x10} a "4 bit (left) shift" rather than "a(n instance of a) shift of 8 bits", may one not then expect that an 8388608 bit shift of a 2^10-byte file to be a 2^10-byte file of all zeros?

Rich Webb Norfolk, VA

Bitstream files, some processes or algorithms use it. Byte alignment of data hardly matters in that case.

Grant

In the case of Huffman encoded the answer on average is yes. The most common byte in the input stream are encoded to the shortest patterns and the least common to the longest. There was a time in the dim and distant past when flash DACs were imprecise and electronics a bit slow when 4, 5 or 6 bit packed bitstream data was sometimes used. 12bit raw image data was sometimes not word aligned in the old days.

The hardware could be made simpler (or sometimes made at all) that way with the tedium of decoding being handled in software. No point wasting bandwidth transmitting around bits you know to be zeroes.

The OP doesn't seem to understand that there is a choice when shifting of either cyclic boundary conditions so that what goes off the top comes back in the bottom (typical for encryption) or arithmetic shift that pads with zero or one depending on signed/unsigned shift operation.

Regards, Martin Brown

Yes (also to Grant) I guess I was locked into the "long word aligned,

16-bit aligned, byte aligned" paradigm, so "not bit aligned" implied an alignment that was smaller than a bit.

Recalling that bytes are not necessarily 8 bits (but may be packed into an 8-bit storage medium) or that the data may be a serial bit stream that is not meaningfully subdivided into smaller units, one sees the OP's dilemma.

Rich Webb Norfolk, VA

What the hell does that even mean? You remember everything you learned

15 years ago and never, ever used again? I also learned Novell networking, think I remember anything?

Now go install paramiko for Python in windows. Do it in less than two minutes, since you're obviously so clever.

Show me!

And if it worked lickety-split, explain to me why it didn't on my generic, same as everyone else's system? That was another merry-go-round of half-assed tutorials with vital information left out, or trivialized.

Hell, just learning Python, how is it obvious that when you download a new module, you DON'T double-click on setup.py? If you DO, all it does is open and close a command prompt super- quickly... So.... Is it installed or not? How would anyone know from the information given? Sure, once you know how, you know.... But why is it always presented with one or two crucial bits missing?

For the curious, you gotta type setup.py install in a command line....

Yeah, SUPER obvious, right?

Just SAY SO. It takes ONE sentence. But then you lose the power from hoarding obscure trivia, eh? Or hey.... just have "install" be the default! WOW! What a concept! Downloading a module you want to install... and have it install when you click on setup... Wow.... I better tell the world!

Why is it always the MOST complicated way that is the default in the software world? Because you can? Because you hate humanity?

I can't wait for my little software romp to be over and I can go back to normal stuff.

Not only is software a complex chaotic ball of assumptions and a never- ending onion of references and definitions, the usual attitude of the software types is repulsive. As seen here.

I'd rather try to steal eggs from a crocodile next time.

Talking about fractional bits does not make much sense as such.

However, talking about fractional values in bits/symbol makes a lot of sense. Assuming that you want to transfer 5 bits (32 separate states) in two symbols will produce 2.5 bits/symbol. As long as receiver for each symbol can destinguish between 0, 1, 2, 3, 4 and 5, this makes perfectly sense.

The byte is usually (at least in C-language) defined as being capable of storing one character in the native character set. On a byte on a

36 bit machine could be 6 or 9 bits. The DEC-10/20 had five 7 characters.

A combuter using UTF-32 as the native character set could use on 64 bit machines (such as Itanium) three 21 bit characters packed into a single 64 bit word.

To avoid such ambiguities, in international standards "octet" is used to indicated _exactly_ 8 bit of data.

If the best student in the class can't remember what he learned, the educational system failed.

Yes and Somewhat. I still remember Forth and Pascal, both learned and used once more than 15 years ago. At least i can figure out how to read manuals and codes.

If i have the need to do so, or being paid to do so. Where's the check?

Files and Bits are the most fundamental things in the software world.

Because I am practical.

I hope you are not designing electronics.

Sounds like you need to drill a hole but don't want to buy a drill or hire someone to do it. And yet you know any other solution leeds to a half-assed result :-)

Failure does not prove something is impossible, failure simply indicates you are not using the right tools... nico@nctdevpuntnl (punt=.) --------------------------------------------------------------

How you can conclude that when I SPECIFICALLY said the resulting file will be bigger? What kind of mutant doesn't understand that I *KNOW* the last bit will be shifted into a new byte, hence a larger file? Shifting is not rotating.

Anyways, here's my code

BinaryInFile =3D open(r"c:\test.bin", "rb") #open to read binary file BinaryOutFile =3D open (r"c:\testOUT.bin", "wb") #open to write binary file

carrybit =3D 0 # set to zero for first time around

while 1: #just keep doing this until the break readbyte =3D BinaryInFile.read(1) #read one byte

if readbyte =3D=3D '' : #returns a null when end of file BinaryInFile.close() BinaryOutFile.write(chr(carrybit*128))#write out last carry bit BinaryOutFile.close() break

a =3D divmod(ord(readbyte),2) #convert char to int and do a modulo 2, shift right

BinaryOutFile.write(chr(a[0] | (carrybit*128))) #write out shifted byte and add carry bit carrybit =3D a[1]

print "done!"

Could it be better? Could it be faster? Probably. But it works.

Thanks for the few helpful replies.

The rest of you autistic software retards: blow it out your arse.

Someone is having a joke with you. A shift of 8388608 bits is the same as a shift of 1048576 million bytes (i.e. 1 Megabyte). A sift that big means the entire file consists or 1's or 0's (depends on the language implantation for shifts). A rotation of 1048576 bytes means you just start reading it from the beginning as is.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required