将Python代码转换为PHP

17

有没有一款软件转换器可以自动将这个Python代码转换为PHP?

#!/usr/bin/python
import math

def calcNumEntropyBits(s):
        if len(s) <= 0: return 0.0
        symCount = {}
        for c in s:
                if c not in symCount: symCount[c] = 1
                else: symCount[c] += 1
        entropy = 0.0
        for c,n in symCount.iteritems():
                prob = n / float(len(s))
                entropy += prob * (math.log(prob)/math.log(2))
        if entropy >= 0.0: return 0.0
        else: return -(entropy*len(s))

def testEntropy(s):
        print "Bits of entropy in '%s' is %.2f" % (s, calcNumEntropyBits(s))

testEntropy('hello world')
testEntropy('bubba dubba')
testEntropy('aaaaaaaaaaa')
testEntropy('aaaaabaaaaa')
testEntropy('abcdefghijk')

1
原来“软件转换器”就是用户本人。 - Kirk Ouimet
1
哈。Stack Overflow需要一个API方法,你可以提交PHP代码并获得Python返回! - JAL
1
@JAL Universal-transpiler 可以将 PHP 编程语言的一个小子集转换为 Python。不过,它仍然是一个正在进行中的工作。 - Anderson Green
6个回答

14

我不知道是否有任何现成的Python转PHP转换器,但将其移植应该是一项微不足道的任务,因为它们之间的相似之处很容易发现:

function calcNumEntropyBits($s) {
        if (strlen($s) <= 0) return 0.0;
        $symCount = array();
        foreach (str_split($s) as $c) {
                if (!in_array($c,$symCount)) $symCount[$c] = 1;
                else $symCount[$c] ++;
        }
        $entropy = 0.0;
        foreach ($symCount as $c=>$n) {
                $prob = $n / (float)strlen($s);
                $entropy += $prob * log($prob)/log(2);
        }
        if ($entropy >= 0.0) return 0.0;
        else return -($entropy*strlen($s));
}

function testEntropy($s):
        printf("Bits of entropy in '%s' is %.2f",$s,calcNumEntropyBits($s));

testEntropy('hello world');
testEntropy('bubba dubba');
testEntropy('aaaaaaaaaaa');
testEntropy('aaaaabaaaaa');
testEntropy('abcdefghijk');
第一个函数中的最后几行也可以写成标准 PHP 三元表达式:
return ($entropy >= 0.0)? 0.0: -($entropy*strlen($s));

1
这很好,但是在PHP中你不能使用foreach迭代字符串。你必须使用带有数字键的for循环。目前这段代码会报错"Invalid argument supplied for foreach()"。 - JAL
我在想是不是log函数的问题?Python提供了更多位数的精度 - math.log(2)为0.69314718055994529,而PHP则显示log(2)为0.69314718056。我很惊讶它们会有这么大的差异。 - JAL
1
考虑到log(2)是除数,且数字的精度在一定程度上是显著的,在这种情况下,累积熵确实可以很大。http://php.net/manual/en/function.log.php中提供了一个bclog()函数的示例,可提高精度。 - bcosca
很好,假设 OP 需要返回与 Python 相同的结果,bclog 在评论中提到的应该可以解决这个问题。 - JAL
我只想说你们所有人都很棒。我正在撰写一篇关于密码强度的研究论文,这对我帮助很大。谢谢! - Kirk Ouimet
显示剩余4条评论

11

我创建了一个名为py2php的Python到PHP转换器。它可以自动翻译基本逻辑,然后您需要调整库调用等。仍处于试验阶段。

以下是通过OP提供的Python自动生成的PHP代码。

<?php
require_once('py2phplib.php');
require_once( 'math.php');
function calcNumEntropyBits($s) {
    if ((count($s) <= 0)) {
        return 0.0;
    }
    $symCount = array();
    foreach( $s as $c ) {
        if (!$symCount.__contains__($c)) {
            $symCount[$c] = 1;
        }
        else {
            $symCount[$c] += 1;
        }
    }
    $entropy = 0.0;
    foreach( $symCount->iteritems() as $temp_c ) {
        $prob = ($n / float(count($s)));
        $entropy += ($prob * (math::log($prob) / math::log(2)));
    }
    if (($entropy >= 0.0)) {
        return 0.0;
    }
    else {
        return -($entropy * count($s));
    }
}

function testEntropy($s) {
    pyjslib_printFunc(sprintf('Bits of entropy in \'%s\' is %.2f', new pyjslib_Tuple([$s, calcNumEntropyBits($s)])));
}

testEntropy('hello world');
testEntropy('bubba dubba');
testEntropy('aaaaaaaaaaa');
testEntropy('aaaaabaaaaa');
testEntropy('abcdefghijk');

由于使用了math导入库和__contains__方法,它无法正确运行,但是这些问题可以很容易地手动修复。


8
我目前正在使用Python制作PHP解释器,完成了大约一半的工作。我可以明确告诉你,有很多主要的边缘情况需要考虑,这会导致成千上万种可能性,几乎不可能将Python移植到PHP。Python的语法比PHP更加强大,而且在语言方面更为前沿,Python的标准库可能是与其同类语言中最先进的之一。
我的建议是,把你的问题往后推一步,问问自己为什么需要基于Python的逻辑在PHP中。尝试将代码转换为其他替代方案,例如从PHP到Python的子进程、使用Gearman使Python在后端处理工作,而PHP则处理视图逻辑,或者更复杂的解决方案是在PHP应用程序和Python服务之间实现服务总线或消息队列。
附言:对于任何可读性问题,我表示歉意。我刚完成了一个为期两天的冲刺。

3

没有这样的工具存在,你需要自己移植代码。


2

1
我曾经也思考过同样的问题,后来在GitHubGist网站上找到了这个PyToPhp.py文件。它很简单,似乎是一个起点,适合初学者。
我打算去看看它!!!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接