简体   繁体   English

Python 从二进制文件中每行只读取一个字符

[英]Python reads only one char per row from a binary file

I have a script which 'encodes' user entered text, for now it's just a string 'python' by default.我有一个“编码”用户输入文本的脚本,现在默认情况下它只是一个字符串“python”。 I am having a problem decoding it.我在解码它时遇到问题。

This is the output with f.tell, where I can see it only reads first byte from each row and outputs only 'pto' instead of 'python'.这是 f.tell 的输出,我可以看到它只从每一行读取第一个字节,并且只输出“pto”而不是“python”。

2
p2
2
2
t2
2
2
o2
2
2
Traceback (most recent call last):
  File "...\file.py", line 73, in <module>
    oa=ord(a)
TypeError: ord() expected a character, but string of length 0 found
>>> 

Somehow it reads without a problem until string of length 0 is found, I can't found where because text.bin is equally spaced, just like key.bin.不知何故,它读取没有问题,直到找到长度为 0 的字符串,我找不到在哪里,因为 text.bin 是等距的,就像 key.bin 一样。

Running xxd -b on text.bin file shows that file contains necessary bytes for decoding.在 text.bin 文件上运行 xxd -b 显示该文件包含解码所需的字节。

00000000: 00000000 00000000 01110000 00000000 00000000 01111001  ..p..y
00000006: 00000000 00000000 01110100 00000000 00000000 01101000  ..t..h
0000000c: 00000000 00000000 01101111 00000000 00000000 01101110  ..o..n
00000012: 00000000 00000000                                      ..

Also key.bin contains them. key.bin 也包含它们。 Here first byte(odd) is an offset between each char in text.bin and second byte (even) is an XOR mask.这里第一个字节(奇数)是 text.bin 中每个字符之间的偏移量,第二个字节(偶数)是一个 XOR 掩码。 I set it to 0 because I haven't thought of a method to generate symetrical bytes to do xor at the end.我将它设置为 0 是因为我还没有想到一种方法来生成对称字节以在最后执行 xor。 I guess I would need XOR cipher for this..我想我需要 XOR 密码来实现这个..

00000000: 00000010 00000000 00000010 00000000 00000010 00000000  ......
00000006: 00000010 00000000 00000010 00000000 00000010 00000000  ......
0000000c: 00000010 00000000 00000010 00000000 00000010 00000000  ......
00000012: 00000010 00000000 00000010 00000000 00000010 00000000  ......
00000018: 00000010                                               .

Here is the current code这是当前的代码

fdata = open("text.bin","wb") ; fmeta = open("key.bin","w+b")
print('Enter a text:')
txt='python' # input()
print('Binary:')
print(" ".join(txt))
l=len(txt)
print(l, 'bytes')
strtobin= ' '.join(format(x, 'b') for x in bytearray(txt, 'utf-8'))
print(strtobin)

shift=int(2)
sh=nobv.to_bytes(1, byteorder='big')

# even bytes in key.bin
for v in range(0, 25, 2): # len(txt)
    #print(v)
    fmeta.seek(v)
    fmeta.write(sh)

# odd bytes in key.bin (contains first part for XOR)
for a in range(0,25): #len(txt)+1
    if a % 2 != 0:
        #print(a)
        fmeta.seek(a)
        fmeta.write(b'\x00')

pad = b'\x00\00'
for line in txt:
    for char in line:
        fdata.write(pad)
        fdata.write(char.encode())
fdata.write(pad)
fdata.close() ; fmeta.close()

f = open ("key.bin", "rb"); d = open ("text.bin", "rb")
f.seek(0); d.seek(0) ; position = 0
while 1:
        #f.seek(2,0)
        offset = f.read(1)
        f.seek(1,0)
        mask = f.read(1)
        
        if not offset: break;
        if not mask: break;

        shift = int(ord(offset))
        position = position + shift
        d.seek(position)
        
        print(f.tell())
        
        a = d.read(1)
        oa=ord(a)
        om=ord(mask)
        output = chr(oa^om)    
        print (output, end="")
f.close() ; d.close()

Your script looked like something I could help with, so I thought I'd give it the old college try.你的剧本看起来像我可以帮忙的东西,所以我想我会在大学里尝试一下。

First problem is at line 15: you didn't define "sh";第一个问题是在第 15 行:你没有定义“sh”; also, the way you wrote your "in range" block will not work on a lot of systems, so I made it look more like your other loop.此外,您编写“in range”块的方式在很多系统上都不起作用,所以我让它看起来更像你的另一个循环。

for v in range(0, 25):
    if v % 2 == 0:
        #print(v)
        fmeta.seek(v)
        fmeta.write(sh)

I'm not sure what you're using that variable for, specifically, so I just added the line sh = b'\\x01' to the list of variables at the top while I as testing the script.我不确定您使用该变量的具体目的是什么,所以我只是在测试脚本时将行sh = b'\\x01'到顶部的变量列表中。 Figure it'd make it easy to spot what the script is actually doing, later.图它可以很容易地发现脚本实际上在做什么,稍后。

Now, at this point, I get the error现在,在这一点上,我得到了错误

oa=ord(a)
TypeError: ord() expected a character, but string of length 0 found 

I suspect the issue is with these two lines: 38: offset = f.read(1) , and 45: shift = int(ord(offset))我怀疑问题出在这两行: 38: offset = f.read(1)和 45: shift = int(ord(offset))

Your program is reading the offset from your file "key.bin", and then stepping that far over into the file "text.bin", and when it goes to a = d.read(1) , sometimes it's reading EOF or a null value.您的程序正在从您的文件“key.bin”中读取偏移量,然后将其移到文件“text.bin”中,当它转到a = d.read(1) ,有时它会读取 EOF 或 a空值。

I'm not entirely sure how to fix the script, here, because I don't understand what your goal output is, but I hope I was able to help, anyway :)我不完全确定如何在这里修复脚本,因为我不明白您的目标输出是什么,但我希望我能够提供帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM