异或密码的实现问题
implementation problems with xor cipher
我尝试使用 python 重新实现书 Applied Cryptography
Protocols, Algorithms, and Source Code in C A book by Bruce Schneier
中的简单 Xor 密码。代码可以在本书的 1.4 节中找到。
书中的 c 代码
/* Usage: crypto key input_file output_file */
void main (int argc, char *argv[])
{
FILE *fi, *fo;
char *cp;
int c;
if ((cp = argv[1]) && *cp!='[=10=]') {
if ((fi = fopen(argv[2], "rb")) != NULL) {
if ((fo = fopen(argv[3], "wb")) != NULL) {
while ((c = getc(fi)) != EOF) {
if (!*cp) cp = argv[1];
c ^= *(cp++);
putc(c,fo);
}
fclose(fo);
}
fclose(fi);
}
}
}
我的 python 版本
import sys
def main(argc, argv):
fi = open(argv[2], 'rb')
fo = open(argv[3], 'wb')
index = 0
while True:
x = fi.read(1)
if not x: break
x = ord(x.decode())
fo.write( chr(x^ord( argv[1][index] )).encode() )
index += 1
if index == len(argv): index = 0
fi.close()
fo.close()
if __name__ == '__main__':
# usage: python3.7 simple_xor.py <key> <inputfile> <outputfile>
main( len(sys.argv), sys.argv )
它们都很好用。 BUT,给定相同的 plaintext(inputfile) 和相同的 key 以上两个代码,他们不treturn相同密文。
然而他们都很好地解密了各自的密文。 (意思变成同一个明文)
我的问题是:为什么他们不生成相同的密文,给定相同的密钥和明文?
C 版本与密钥 XOR 单个 bytes。 Python 版本使用 encode()
和 decode()
,适用于 个字符 ,而不是 个字节 。尝试使用重音字符或表情符号而不是 ASCII 字符来查看差异。
此外,将 index
包裹到 0
的条件是错误的;您没有将它与密钥的长度进行比较。
也就是说,这个问题更多的是关于如何使用 Python 而不是密码学。
我做了非常小的改动 运行 它针对 C 版本,这似乎如您所愿:
我为 argv[1] 添加了一个键值分配,并将 #ord(x.decode()) 更改为 int(x.hex(),16).
我从 c 代码中解密了密文,密文似乎与 python 生成的密文相同,输出是正确的。我用过:
cat cypher.txt
Cypher
./a.out key cypher.txt cypher.out
./crypt.py key cypher.out cypher.txt.test
密文相同:
$ ./a.out key cypher.txt cypher.out
$cat cypher.out
(
a
$ ./crypt.py key cypher.txt cypher2.out
$ cat cypher2.out
(
a
更新后的 python 代码:
#!/usr/local/opt/python3
import sys
def main(argc, argv):
key=argv[1]
fi = open(argv[2], 'rb')
fo = open(argv[3], 'wb')
index = 0
while True:
x = fi.read(1)
if not x: break
x = ord(x.decode()) #int(x.hex(),16)
fo.write( chr(x^ord( key[index] )).encode() )
index += 1
if index == len(key): index = 0
fi.close()
fo.close()
if __name__ == '__main__':
# usage: python3.7 simple_xor.py <key> <inputfile> <outputfile>
main( len(sys.argv), sys.argv )
我尝试使用 python 重新实现书 Applied Cryptography
Protocols, Algorithms, and Source Code in C A book by Bruce Schneier
中的简单 Xor 密码。代码可以在本书的 1.4 节中找到。
书中的 c 代码
/* Usage: crypto key input_file output_file */
void main (int argc, char *argv[])
{
FILE *fi, *fo;
char *cp;
int c;
if ((cp = argv[1]) && *cp!='[=10=]') {
if ((fi = fopen(argv[2], "rb")) != NULL) {
if ((fo = fopen(argv[3], "wb")) != NULL) {
while ((c = getc(fi)) != EOF) {
if (!*cp) cp = argv[1];
c ^= *(cp++);
putc(c,fo);
}
fclose(fo);
}
fclose(fi);
}
}
}
我的 python 版本
import sys
def main(argc, argv):
fi = open(argv[2], 'rb')
fo = open(argv[3], 'wb')
index = 0
while True:
x = fi.read(1)
if not x: break
x = ord(x.decode())
fo.write( chr(x^ord( argv[1][index] )).encode() )
index += 1
if index == len(argv): index = 0
fi.close()
fo.close()
if __name__ == '__main__':
# usage: python3.7 simple_xor.py <key> <inputfile> <outputfile>
main( len(sys.argv), sys.argv )
它们都很好用。 BUT,给定相同的 plaintext(inputfile) 和相同的 key 以上两个代码,他们不treturn相同密文。
然而他们都很好地解密了各自的密文。 (意思变成同一个明文)
我的问题是:为什么他们不生成相同的密文,给定相同的密钥和明文?
C 版本与密钥 XOR 单个 bytes。 Python 版本使用 encode()
和 decode()
,适用于 个字符 ,而不是 个字节 。尝试使用重音字符或表情符号而不是 ASCII 字符来查看差异。
此外,将 index
包裹到 0
的条件是错误的;您没有将它与密钥的长度进行比较。
也就是说,这个问题更多的是关于如何使用 Python 而不是密码学。
我做了非常小的改动 运行 它针对 C 版本,这似乎如您所愿:
我为 argv[1] 添加了一个键值分配,并将 #ord(x.decode()) 更改为 int(x.hex(),16).
我从 c 代码中解密了密文,密文似乎与 python 生成的密文相同,输出是正确的。我用过:
cat cypher.txt
Cypher
./a.out key cypher.txt cypher.out
./crypt.py key cypher.out cypher.txt.test
密文相同:
$ ./a.out key cypher.txt cypher.out
$cat cypher.out
(
a
$ ./crypt.py key cypher.txt cypher2.out
$ cat cypher2.out
(
a
更新后的 python 代码:
#!/usr/local/opt/python3
import sys
def main(argc, argv):
key=argv[1]
fi = open(argv[2], 'rb')
fo = open(argv[3], 'wb')
index = 0
while True:
x = fi.read(1)
if not x: break
x = ord(x.decode()) #int(x.hex(),16)
fo.write( chr(x^ord( key[index] )).encode() )
index += 1
if index == len(key): index = 0
fi.close()
fo.close()
if __name__ == '__main__':
# usage: python3.7 simple_xor.py <key> <inputfile> <outputfile>
main( len(sys.argv), sys.argv )