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实现的主要内容,如果未能解决你的问题,请参考以下文章

MySQL中的RAND()函数使用

为啥 sklearn 在实现 rand 索引时需要真实标签?

python 用包装器实现二进制rand搜索

SQL Server 中的伪随机可重复排序(不是 NEWID() 和 RAND())

excel中的rand函数的使用教程详解

javascript 香草JS中的rand和randhsl颜色处理