如何解析文件并使用数据解密另一个文件的数据?

问题描述 投票:2回答:2

我尝试在循环中替换字符,我得到了类似的代码

$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); 
}
php parsing encryption str-replace
2个回答
2
投票

你的第一个问题是,fgets返回包含新行字符的文本(并取决于系统回车)。

你的第二个问题是,一些“字母”的长度不是“一个字符”(即最后的unicode字符)。

第三个问题是,如果加密方案发生变化,您可能会遇到意外结果。假设您的加密方案就是这样:

a => 1
b => 12
c => 2

明显是12的文本b将变成ac(因为顺序)。

在我看来,这导致了结论,mickmackusa的答案是最好的 - 特别是他的答案的第二部分,通过代码通过密文代码。

my old solution

我可能会用

$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
}

2
投票

我刚用我的样本数据在我的本地主机上测试了这个。

在这里使用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);
}
© www.soinside.com 2019 - 2024. All rights reserved.