同明文同密钥下C与Python实现Xor cipher密文不一致原因问询
问题原因分析与修复方案
你的Python实现和C代码生成不同密文的核心原因是密钥循环逻辑不一致,还有一处编码处理的细节差异,下面逐一拆解说明:
1. 密钥循环的关键错误
先看原版C代码的密钥循环逻辑:
while ((c = getc(fi)) != EOF) { if (!*cp) cp = argv[1]; // 当指针走到密钥末尾,立刻重置回密钥开头 c ^= *(cp++); // 使用当前密钥字符,然后指针后移一位 putc(c,fo); }
C代码会严格遍历密钥的每一个字符,当用完整个密钥(指针cp触碰到字符串末尾的\0终止符),就马上重置到密钥的起始位置,循环复用密钥。
而你的Python代码里,密钥循环的判断条件写错了:
index += 1 if index == len(argv): # 这里是核心错误! index = 0
len(argv)是整个命令行参数的总数量(比如运行python simple_xor.py key in out时,len(argv)等于4),而不是密钥字符串的实际长度len(argv[1])。这会导致:
- 密钥没有在正确的位置重置,要等到
index增长到命令行参数总数时才会回到开头; - 如果密钥长度小于
len(argv),还会触发索引越界错误(你测试时没报错可能是巧合,比如密钥长度刚好等于len(argv)-1,或者输入文件很短还没走到越界的位置)。
2. 编码处理的次要差异
C代码是直接处理二进制字节(getc读取单个字节,不关心编码),而你的Python代码里用了x.decode():
x = ord(x.decode())
这会默认假设输入文件的字节是UTF-8编码的,如果输入文件包含非UTF-8的二进制数据(比如图片、压缩包),decode()会直接报错,和C代码的二进制处理逻辑不一致。
修复后的Python代码
把密钥循环的判断条件修正为基于密钥长度,同时改成直接处理字节的方式,和C代码完全对齐:
import sys def main(argv): # 先做参数校验,和C代码的逻辑对齐 if len(argv) != 4: print("Usage: python simple_xor.py <key> <inputfile> <outputfile>") return key = argv[1] if not key: print("Key cannot be empty!") return key_len = len(key) index = 0 try: # 用with语句自动管理文件关闭,更安全 with open(argv[2], 'rb') as fi, open(argv[3], 'wb') as fo: while True: byte = fi.read(1) if not byte: break # 直接处理字节,不需要decode,和C逻辑一致 plain_byte = byte[0] key_byte = ord(key[index]) cipher_byte = plain_byte ^ key_byte fo.write(bytes([cipher_byte])) index += 1 if index == key_len: index = 0 except FileNotFoundError as e: print(f"Error: File not found - {e.filename}") except Exception as e: print(f"Error occurred: {str(e)}") if __name__ == '__main__': main(sys.argv)
验证修复效果
修复后,用相同的明文和密钥,Python代码生成的密文会和C代码完全一致,因为:
- 密钥循环逻辑和C代码完全同步:用完密钥的最后一个字符后立刻重置到开头;
- 直接处理二进制字节,和C代码的字节级操作逻辑完全匹配。
内容的提问来源于stack exchange,提问作者user71756
相关产品推荐
相关产品推荐

