【问题标题】:Convert some C function to Python [closed]将一些 C 函数转换为 Python [关闭]
【发布时间】:2013-02-14 01:19:15
【问题描述】:

我需要将此函数在 C 中转换为 Python:

void myencrypt(char password[],int mkey)
{
    unsigned int i;
    for(i=0;i<strlen(password);++i)
    {
    password[i] = password[i] - mkey;
    }
}

我尝试了这个,但失败了......

def myencrypt(password, mkey):

    i = 0
    newpass = []

    for i in range(len(password)):
        newpass[i] = ord(password[i]) - mkey;

    return newpass

有什么帮助吗?

【问题讨论】:

  • 使用追加。但是为什么首先要从 c 转换为 python 呢?只需保留您的 c 代码并使用 cython 包装
  • 您是否有理由不使用chr 将数字转换回字符? (在 C 语言中,这不是必需的,因为 'a'97 是相同的值。但在 Python 中,就像您需要 ord 将一个转换为另一个一样,您需要 chr 转换另一个方式。)

标签: python c linux encryption


【解决方案1】:

C 代码正在就地修改password。因此,最接近的等价物是:

def myencrypt(password, mkey):
    for i in range(len(password)):
        password[i] = chr(ord(password[i]) - mkey)

假设passwordlist 字符,而不是字符串。

另外,请注意,我在每个 ord(password[i]) - mkey 的结果上调用 chr,因为否则你将用数字替换每个字符 - 例如,myencrypt(['a'], 32) 会给你[65] 而不是@ 987654329@。 (这在 C 中不是必需的,因为 65'A' 在 C 中是相同的值。)

您更有可能希望使用字符串调用此函数,并返回一个字符串。您可以仍然使用 C 风格的就地功能来做到这一点,只需转换和转换回来:

def myencrypt(password, mkey):
    newpass = list(password)
    for i in range(len(newpass)):
        newpass[i] = chr(ord(newpass[i]) - mkey)
    return ''.join(newpass)

但是,这不是一种非常 Pythonic 的做事方式。更惯用的解决方案是:

def myencrypt(password, mkey):
    return ''.join(chr(ord(ch) - mkey) for ch in password)

这带来了一个更普遍的观点:除了在非常琐碎的情况下,直接尝试“将 C 代码转换为 Python”是一个坏主意。相反,要弄清楚 C 代码的作用,并编写新的 Python 代码,以最适合 Python 的方式完成相同的任务,而不是按照 C 代码的方式。

【讨论】:

    【解决方案2】:

    在 Python 中,如果列表足够长,则只能分配给列表中的索引,否则会出现 IndexError。请尝试以下操作:

    def myencrypt(password, mkey):
        i = 0
        newpass = []
        for i in range(len(password)):
            newpass.append(ord(password[i]) - mkey)
        return newpass
    

    通过使用newpass.append(),您只需将每个新元素添加到列表的末尾。附带说明一下,您可以直接遍历 password 的元素,这样更简洁:

    def myencrypt(password, mkey):
        newpass = []
        for x in password:
            newpass.append(ord(x) - mkey)
        return newpass
    

    【讨论】:

    • 当你改进 OP 的代码时,去掉不必要的i = 0,也许解释一下缺少的chr,它可能值得显示等效的列表理解,它变成了 4行到 1.
    【解决方案3】:

    首先,我不会在这个函数中使用“加密”这个词。在现代 Python 中,您可以使用可变的 bytearray 对象。然后转成字符串。

    def myobfuscate(password, mkey):
        a = bytearray(password)
        for i, c in enumerate(password):
            a[i] = ord(c) - mkey
        return str(a)
    
    
    myobfuscate("secret", 10)
    # OUT: 'i[Yh[j'
    

    在 Python 中,字符串是不可变的,它们不能就地更改。所以你会使用这样的函数:

    pw = myobfuscate(pw, 10)
    

    假设您不再需要原始值。这将使用函数返回的新对象替换原始引用。

    【讨论】:

    • return ''.join(chr(ord(c) - mkey) for c in password)
    • bytearray 的元素是整数,而不是字符,所以应该是 a[i] -= mkey(或者,如果你愿意,a[i] = ord(c) - mkey)。 (在 2.7 中,chr 是无害的,即使文档另有说明;在 3.x 中,它会引发异常。)
    • @Jon-Eric:这与 Keith 的答案完全不同。作为对 F.J 答案的评论,它可能很有用,因为它 等同于(并且比他的更短,并且可能比 Python 更多)。
    • @abarnert 很公平。
    • @Jon-Eric 是的,但是对于那些刚接触 Python 的人,我尝试让示例更简单一些。
    猜你喜欢
    • 2020-10-17
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    相关资源
    最近更新 更多