我必须将旧的 Perl 脚本升级到 php。该脚本对密码进行一些编码以存储在我们的数据库中,如下所示:-
$pw =~ tr/a-zA-Z/h-za-gH-ZA-G/;
因此 /a-zA-Z/ 中的每个字母都被 /h-za-gH-ZA-G/ 中的等效字母替换
我正在尝试找到一种在 PHP 中执行相同操作的方法?
我查看了 str_replace 但这似乎涉及编写一个长数组而不是像 perl 这样的替换模式
一般来说该函数称为 strtr():
strtr($string, $from, $to);
这种形式有三个参数:
$string
将被翻译,返回值是翻译后的字符串。
这里
$from
和 $to
包含要从 -> 转换到的字节,因此两个字符串应该具有相同的字节大小(参见 strlen())。
$secret = strtr(
$plain,
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'hijklmnopqrstuvwxyzabcdefgHIJKLMNOPQRSTUVWXYZABCDEFG',
);
现在,与 Perl 翻译运算符相比,该函数的不同之处在于,您没有 26 个字节的内部短格式
a-z
。
为此,您可以使用 range() 函数,它也适用于字节(字符),但是它返回一个数组,然后您可以内爆或使用带有两个参数的 strtr(),仅当第二个参数是数组。
$string = "hello, world!\n";
$from = range('a', 'z');
$to = [...range('h', 'z'), ...range('a', 'g')];
echo strtr($string, array_combine($from, $to)); // olssv, dvysk!
使用数组的第二种形式具有额外的好处,您可以替换多个字节,也可以替换不同长度的字节(例如 UTF-8)。但请注意,range() 与手册中的内容不兼容:
如果 start 或 end 是具有多个字节的非数字字符串,则会发出 E_WARNING。
请参阅手册页了解所有详细信息:
没有找到大象PHP代码格式器并且不想深入搜索,这里是可以将模式作为字符串进行操作的函数,如上所述:
$string = "hello, world!\n";
$fn = fn(string $string, string $pattern) => strtr(
$string,
array_combine(
...array_map(fn(string $ranges) => array_merge(
...array_map(fn(string $range) => range(
...sscanf($range, '%[^-]-%[^-]')), str_split($ranges, 3))),
sscanf($pattern, 'tr/%[^/]/%[^/]/'))));
echo $fn($string, 'tr/a-zA-Z/h-za-gH-ZA-G/'); // olss, dvysk!
虽然 PHP 中有 Perl 兼容的正则表达式 (PCRE),但此示例未使用任何 preg_*() 函数。
我尝试创建一些相对容易阅读的代码:
<?php
function getRanges(array $pairs): string
{
$result = '';
foreach ($pairs as $pair) {
[$start, $finish] = $pair;
$result .= implode('', range($start, $finish));
}
return $result;
}
function perlReplace(string $input): string
{
return strtr($input,
getRanges([['a', 'z'], ['A', 'Z']]),
getRanges([['h', 'z'], ['a', 'g'], ['H', 'Z'], ['A', 'G']]));
}
echo perlReplace('My PassWord');
这将返回
Tf WhzzDvyk
。这和 hakre 刚才的回答非常相似。
呃,我需要指出这是一种在数据库中存储密码的非常糟糕的方法吗?看看 password_hash()。提高安全性永远不会太晚。
如果你想在 php 中创建一个简单的加密映射,你可以使用 strtr() 函数,如下所示:
$password = 'GooglePleaseLetMeBeOneOfYourIntern'
$from = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$to = 'hijklmnopqrstuvwxyzabcdefgHIJKLMNOPQRSTUVWXYZABCDEFG';
return strtr($password, $from, $to); //return the password crypted by the mapping