我尝试在循环中替换字符,我得到了类似的代码
$my_file = 'encrypted_text.txt';
$handle = fopen($my_file, 'r');
$data = fread($handle,filesize($my_file));
echo "\n".$data."\n";
$file = fopen("encryption_scheme.txt", "r");
$members = array();
while (!feof($file))
{
$code = substr(fgets($file), strrpos(fgets($file), '=> ' )+1);
$code = str_replace('>', '', $code);
$code = str_replace(' ', '', $code);
$letter = substr(fgets($file), 0, 1);
$data = str_replace(',', ' ', $data);
$data = str_replace($code, $letter, $data);
}
echo $data;
fclose($file);
但不是获得解密文本,而是重复代码,如
631005,323151,810236,60916,384244,346538,404479
631005 323151 810236 60916 384244 346538 404479
更新
while (!feof($file))
{
$text = fgets($file);
$code = substr($text, strrpos($text, '=> ' )+1);
$code = str_replace('>', '', $code);
$code = str_replace(' ', '', $code);
$letter = substr($text, 0, 1);
$data = str_replace(',', ' ', $data);
$data = str_replace($code, $letter, $data);
}
你的第一个问题是,fgets
返回包含新行字符的文本(并取决于系统回车)。
你的第二个问题是,一些“字母”的长度不是“一个字符”(即最后的unicode字符)。
第三个问题是,如果加密方案发生变化,您可能会遇到意外结果。假设您的加密方案就是这样:
a => 1
b => 12
c => 2
明显是12
的文本b
将变成ac
(因为顺序)。
在我看来,这导致了结论,mickmackusa的答案是最好的 - 特别是他的答案的第二部分,通过代码通过密文代码。
我可能会用
$data = str_replace(',', ' ', $data); // do this once, not every iteration
while($text = fgets($file) { // fgets returns false on eof
list($letter, $code) = explode(' => ', $text, 2);
$code = trim($code); // <-- removes whitespace and new lines and so on
$data = str_replace($code, $letter, $data);
}
更新:
// expand the text, if no "=>" is found:
while(...) {
if(strpos($text, '=>') === FALSE) {
$text = fgets($text);
}
if(!trim($text)) { // completely empty lines, even after expanding (EOF)
break;
}
// rest as before
}
我刚用我的样本数据在我的本地主机上测试了这个。
在这里使用preg_match_all()
的优势(虽然有些人担心正则表达式模式)是php没有110x的电池串替换来实现结果。
在工作中看到正则表达式:https://regex101.com/r/HAQEuK/2
码:
$encryption_scheme = file_get_contents('encryption_scheme.txt');
if (!preg_match_all('~(.*?) => (\d+)(?: *\R|$)~s', $encryption_scheme, $matches, PREG_SET_ORDER)) {
echo 'Failed to extract encryption scheme.';
} else {
$translator = array_combine(array_column($matches, 2), array_column($matches, 1));
$translator[','] = ' '; // replace commas with spaces
$encrypted_text = file_get_contents('encrypted_text.txt');
echo strtr($encrypted_text, $translator);
}
输出:
z C F I L O R
正则表达式模式说:
[space] => [space]
之前捕获子字符串,然后捕获同一行中的数字子字符串,然后匹配/使用尾随空格和行返回(除了最后一行没有返回匹配的行)。array_combine()
允许您从两列捕获的数据生成关联数组。为了更准确并防止意外替换,您可以单独处理每个整数并在解密后将其内爆。
$encryption_scheme = file_get_contents('encryption_scheme.txt');
if (!preg_match_all('~(.*?) => (\d+)(?: *\R|$)~s', $encryption_scheme, $matches, PREG_SET_ORDER)) {
echo 'Failed to extract encryption scheme.';
} else {
$translator = array_combine(array_column($matches, 2), array_column($matches, 1));
$encrypted_text = file_get_contents('encrypted_text.txt');
$decrypted = [];
foreach (explode(',', $encrypted_text) as $integer) {
$decrypted = $translator[$integer] ?? $integer;
}
echo implode(' ', $decrypted);
}