我使用Python找到了Andre's answer的价值。
与提问者一样,我需要一个php解决方案,所以我将安德烈的代码改写为PHP。如果有人觉得有用,我在这里发布它。
然而,它存在着与Python版本不同的限制:
它似乎无法编码任何大于8个字符的字符串。这可能是可以解决的问题?这与PHP如何处理非常大的整数有关。幸运的是,对于我的用例,我只需要编码少于8个字符。它可能在不同的环境下工作,我不确定。总之,在声明这一警告后,这是该类:
<?php
class KeyGen
{
protected $alphabet;
protected $groups;
protected $separator;
public function __construct(string $alphabet = null, int $groups = 4, string $separator = '-')
{
$alphabet = $alphabet ?: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$this->alphabet = str_split($alphabet);
$this->groups = $groups;
$this->separator = $separator;
}
public function encode(string $txt)
{
$asciiVals = array_map('ord', str_split($txt));
$num = array_reduce($asciiVals, function($x, $y) {
return ($x * 256) + $y;
});
$a = [];
$i = 0;
$n = count($this->alphabet);
while ($num > 0) {
$i = $num % $n;
array_push($a, $this->alphabet[$i]);
$num -= $i;
$num = intdiv($num, $n);
}
$str = implode('', $a);
if($this->groups > 0) {
while (strlen($str) % $this->groups != 0) {
$str .= $this->alphabet[0];
}
}
if($this->groups) {
$split = str_split($str, $this->groups);
$str = implode($this->separator, $split);
}
return $str;
}
public function decode(string $txt)
{
$stripped = str_replace($this->separator, '', $txt);
$stripped = rtrim($stripped, $this->alphabet[0]);
$alphabetPosistions = [];
foreach(str_split($stripped) as $char){
array_push($alphabetPosistions, array_search($char, $this->alphabet));
}
$alphabetPosistions = array_reverse($alphabetPosistions);
$num = array_reduce($alphabetPosistions, function($x, $y) {
$n = count($this->alphabet);
return ($x * $n) + $y;
});
$a = [];
$i = 0;
$n = count($this->alphabet);
while ($num > 0) {
$i = $num % 256;
array_push($a, $i);
$num -= $i;
$num = intdiv($num, 256);
}
return implode('', array_map('chr', array_reverse($a)));
}
}
以下是一个使用示例,对"ABC123"进行编码和解码:
$keyGen = new KeyGen();
$encoded = $keyGen->encode('ABC123');
$decoded = $keyGen->decode('3WJU-YSMF-P000');