python中的rand和rands实现
Posted
技术标签:
【中文标题】python中的rand和rands实现【英文标题】:rand and rands implementation in python 【发布时间】:2019-09-04 13:06:06 【问题描述】:我需要在 python 中从 c++ 中实现 rand 和 rands 来重新加密一堆文件。但似乎无法正确处理。
我有一个将文件解密为文本的 exe,我还需要源代码,在编辑文件后我需要使用相同的方法对其进行加密。
由于我不知道如何编写 c++ 代码,我选择了用 python 编写。先尝试解密才知道方法是一样的。
以下代码是未加密文件的c++代码,其中“buff”是加密块的开头,“len”是该块的长度。
static const char KEY[] = "KF4QHcm2";
static const unsigned long KEY_LEN = sizeof(KEY) - 1;
void unobfuscate(unsigned char* buff, unsigned long len)
srand((char)buff[len - 1]);
for (unsigned long i = 0; i < len - 2; i += 2)
buff[i] ^= KEY[rand() % KEY_LEN];
据我了解,它将加密块的最后一个字符作为种子,并且从一开始每 2 个字节将值与 KEY 数组的元素进行异或,该索引由随机数的余数确定除以 KEY 长度。
在网上搜索,我发现 c++ 使用了一个简单的Linear Congruential Generator,不应该用于加密,但似乎无法使其工作。
我找到了one example of the code 并尝试实现另一个,但似乎都不起作用。
#My try at implementing it
def rand():
global seed
seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)
return seed
我还看到 rand 函数介于 0 和 RAND_MAX 之间,但找不到 RAND_MAX 的值,如果我找到它,也许可以使用 random.randrange()。
这也可以是我设置种子的方式,因为在 c++ 中似乎 char 有效,但在 python 中,我将其设置为字符的值。
这是我在使用各种方法对文件进行解密时观察到的情况。这只是前 13 个字节,所以如果有人需要检查它是否有效,可以这样做。
The block ends with the sequence: 4C 0A 54 C4 this means C4 is the seed
Example encrypted:
77 43 35 69 26 6B 0C 6E 3A 74 4B 33 71 wC5i&k.n:tK3q
Example un-encrypted using c++:
24 43 6C 69 63 6B 49 6E 69 74 0A 33 34 $ClickInit.34
Example un-encrypted using python example:
1A 43 7E 69 77 6B 38 6E 0E 74 1A 33 3A .C~iwk8n.t.3:
Example un-encrypted using python implementation:
3C 43 73 69 6E 6B 4A 6E 0E 74 1A 33 37 <CsinkJn.t.37
我的python脚本也可能有问题,所以这里是文件以防它有任何错误:
import os
def srand(s):
global seed
seed = s
def rand():
global seed
#Example code
#seed = (seed * 214013 + 2531011) % 2**64
#return (seed >> 16)&0x7fff
#Implementation code
seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)
return seed
KEY = ['K','F','4','Q','H','c','m','2']
KEY_LEN = len(KEY) - 1
for filename in os.listdir("."):
if filename.endswith(".dat"):
print(" Decoding " + filename)
#open file
file = open(filename, "rb")
#set file attributes
file_length = os.path.getsize(filename)
file_buffer = [0] * file_length
#copy contents of file to array
for i in range(file_length):
file_buffer[i] = int.from_bytes(file.read(1), 'big')
#close file
file.close()
print(" Random Seed: " + chr(file_buffer[-1]))
#set random generator seed
srand(file_buffer[-1])
#decrypt the file
for i in range(3600, file_length, 2):
file_buffer[i] ^= ord(KEY[rand() % KEY_LEN])
#print to check if output is un-encrypted
for i in range(3600, 3613, 1):
print(file_buffer[i])
print(chr(file_buffer[i]))
continue
else:
#Do not try to un-encrypt the python script
print("/!\ Can't decode " + filename)
continue
如果有人能帮我解决这个问题,我将不胜感激,如果可能的话,我希望它能够在 python 中工作,但据我所知,似乎我必须学习 c++ 才能让它工作。
【问题讨论】:
rand
在 C++ 中基本上是一个实现定义的函数。如果您希望代码可移植,我建议您使用类似 messner twister (std::mt19937
)
@NathanOliver -- s/messner/mersenne/.
【参考方案1】:
rand
不是加密函数。
rand
的算法在系统编译器或其他任何东西之间不稳定。
如果您别无选择,最好的办法是使用 python-C/C++ 互操作性技术并实际运行 rand()
和 srand()
。这会很糟糕,但它会和原始代码一样糟糕。
【讨论】:
以上是关于python中的rand和rands实现的主要内容,如果未能解决你的问题,请参考以下文章
为啥 sklearn 在实现 rand 索引时需要真实标签?