我正在尝试解决加密问题(https://callicode.fr/pydefis/Reverse/txt),算法使用以下C函数(F1)。 我不知道C,我试图将它转换为python(F2)但没有成功。提前谢谢你让我知道我做错了什么。
F1:
void Encrypt(unsigned char key[20], unsigned char *pPlainBuffer, unsigned char *pCipherBuffer, unsigned int nLength)
{
int nKeyPos = 0;
unsigned int n;
unsigned char KeyA = 0;
if ((pPlainBuffer != NULL) && (pCipherBuffer != NULL)) {
for (n = 0; n < 20; n++)
KeyA ^= key[n];
nKeyPos = KeyA % 20;
for (n = 0; n < nLength; n++) {
pCipherBuffer[n] = pPlainBuffer[n]^(key[nKeyPos]*KeyA);
KeyA += pCipherBuffer[n];
nKeyPos = pCipherBuffer[n] % 20;
}
}
}
F2:
def Encrypt(plainText, key): # plainText is a list of hexadecimals representing ascii
# characters, key is a list of int size 20 each int
# beetween 0 and 255
keyA = 0
for n in range(20):
keyA ^= key[n]
nKeyPos = KeyA % 20
for n in range(len(plainText)):
codedText[n] = plainText[n]^(key[nKeyPos]*KeyA)
keyA += codedText[n]
nKeyPos = codedText[n] % 20
答案 0 :(得分:1)
这是一个小小的工作示例:
def Encrypt(key, pPlainBuffer):
nKeyPos = 0
KeyA = 0
if pPlainBuffer is not None:
pCipherBuffer = []
for n in range(20):
KeyA = KeyA ^ key[n]
nKeyPos = KeyA % 20
for n in range(len(pPlainBuffer)):
pCipherBuffer.append(pPlainBuffer[n] ^ (key[nKeyPos] * KeyA))
KeyA += pCipherBuffer[n]
nKeyPos = pCipherBuffer[n] % 20
return pCipherBuffer
def Decrypt(key, pCipherBuffer):
nKeyPos = 0
KeyA = 0
if pCipherBuffer is not None:
pPlainBuffer = []
for n in range(20):
KeyA ^= key[n]
nKeyPos = KeyA % 20
for n in range(len(pCipherBuffer)):
pPlainBuffer.append(pCipherBuffer[n] ^ (key[nKeyPos] * KeyA))
KeyA += pCipherBuffer[n]
nKeyPos = pCipherBuffer[n] % 20
return pPlainBuffer
if __name__ == "__main__":
import random
key = [random.randint(0, 255) for k in range(20)]
pPlainBuffer = [ord(c) for c in "this is the unencrypted message"]
a = Encrypt(key, pPlainBuffer)
b = Decrypt(key, a)
print("-"*80)
print("Encrypted message")
print("-"*80)
print(":".join("{:02x}".format(c) for c in a))
print("-"*80)
print("Decrypted message")
print("-"*80)
print("".join([chr(c) for c in b]))
# --------------------------------------------------------------------------------
# Encrypted message
# --------------------------------------------------------------------------------
# 1ba:2678:197df9:bec4844:2d163e70c:1d01cf925ab:45512ab14a9b:4724251445d50:550934523b78ca:1f34a7cfbb7db6a1:1bfb485c731bcdb713:161112a22402868312ad:b1696bc757013314e2975:531cf11bdcc471dc32befef:a2627edf4f99a01240ba016f:839c3758163127edc2e955cc63:100437038699e709cce258a3ed1b:6c7fa638eaa735df4ae48a03e32a9:58911d1d6ea1c00863052f0fa160a0d:2c7f52a5aa98fec79d57f011bf256acf0:22559e3d644a5d56f620427531855711f90:81693c9711311b3cfe601f0f44c5ec6c8eb9:6a628fdbfce204d77db6eb221a161b683dee6a:c86f7e57fa208eaff7fbe01b26048cae230f1a8:308b00994e93e28e9e0f004693351a122c7da861d:2bc2e905f06bc052ef96e3dd7d68389e9df11483546:9717a6cd2ce3ac9b8757110bab10b835b11adda93df2:12072f89ef89b60cbd3d4c3735dda19daddbeecfd47b5d:1084c8b9afea8c4ece5432ef4130712f4f9a5a403acac323:27679b285784a6a9f1d42189acfc9433655c776e5ce16d191:1c6f807e0f27d47ad8ee72ba6740cb5dee4d918da413efe2f6d
# --------------------------------------------------------------------------------
# Decrypted message
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# this is the unencrypted message
这几乎是1:1 c ++重写版本,但如果你想要一个更加pythonic的版本:
def encrypt(key, plain_buffer):
key_pos = 0
key_a = 0
cipher_buffer = []
if plain_buffer is not None:
for k in key:
key_a = key_a ^ k
key_pos = key_a % 20
for n, d in enumerate(plain_buffer):
cipher_buffer.append(d ^ (key[key_pos] * key_a))
key_a += cipher_buffer[n]
key_pos = cipher_buffer[n] % 20
return cipher_buffer
def decrypt(key, cipher_buffer):
key_pos = 0
key_a = 0
plain_buffer = []
if cipher_buffer is not None:
for k in key:
key_a ^= k
key_pos = key_a % 20
for n, d in enumerate(cipher_buffer):
plain_buffer.append(d ^ (key[key_pos] * key_a))
key_a += cipher_buffer[n]
key_pos = cipher_buffer[n] % 20
return plain_buffer
if __name__ == "__main__":
import random
random.seed(1)
key = [random.randint(0, 255) for k in range(20)]
plain_buffer = [ord(c) for c in "this is the unencrypted message"]
a = encrypt(key, plain_buffer)
b = decrypt(key, a)
print("-" * 80)
print("Encrypted message")
print("-" * 80)
print(":".join("{:02x}".format(c) for c in a))
print("-" * 80)
print("Decrypted message")
print("-" * 80)
print("".join([chr(c) for c in b]))
虽然没有使用未签名的字符,但这就是加密消息看起来那么大的原因。
答案 1 :(得分:1)
你有很多问题......最明显的是python整数默认不限制为字节宽度,因此你必须明确设置宽度
另外你必须把字母转换成python中的数字,因为它们是根本不同的东西(用C / c ++字母实际上只是数字)
def Encrypt(plainText, key): # plainText is a list of hexadecimals representing ascii
# characters, key is a list of int size 20 each int # beetween 0 and 255
keyA = 0
for letter in key:
keyA ^= ord(letter) # conver letter to number
keyA = keyA & 0xFF # fix width to one byte
key = itertools.cycle(key) # repeate forever
codedText = ""
for letter,keyCode in zip(plainText,key):
xorVal = (ord(keyCode) * keyA) & 0xFF # make one byte wide
newLetter = chr((ord(letter) ^ xorVal )&0xFF) # make one byte wide
codedText += newLetter
keyA += ord(newLetter)
keyA = keyA&0xFF # keep it one byte wide