8

我是 Xor 加密的新手,我在使用以下代码时遇到了一些问题:

function xor_this($string) {

// Let's define our key here
 $key = ('magic_key');

 // Our plaintext/ciphertext
 $text =$string;

 // Our output text
 $outText = '';

 // Iterate through each character
 for($i=0;$i<strlen($text);)
 {
     for($j=0;$j<strlen($key);$j++,$i++)
     {
         $outText .= $text{$i} ^ $key{$j};
         //echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
     }
 }  
 return $outText;
}

当我运行它时,它适用于普通字符串,如“dog”,但它仅部分适用于包含数字的字符串,如“12345”。

展示...

xor_this('dog')='UYV'

xor_this('123')=''

注意到xor_this( xor_this('123') )= '123' 也很有趣,正如我所期望的那样。我很确定问题出在我对按位运算符的模糊理解中,或者可能是 PHP 处理包含数字的字符串的方式。我敢打赌那里有聪明的人确切地知道这里出了什么问题。谢谢。

编辑#1:这不是真正的“加密”。我想混淆是正确的术语,这就是我正在做的事情。我需要从用户那里传递一个包含不重要数据的代码,而他们不能轻易地篡改它。他们正在离线完成一项定时活动,并通过此代码将他们的时间提交到在线记分牌。离线活动将混淆他们的时间(以毫秒为单位)。我需要编写一个脚本来接收此代码并将其转换回包含他们时间的字符串。

4

9 回答 9

4

我是怎么做到的,可能会对某人有所帮助...

$msg = 'say hi!';
$key = 'whatever_123';

// print, and make unprintable chars available for a link or alike.
// using $_GET, php will urldecode it, if it was passed urlencoded
print "obfuscated, ready for url: " . urlencode(obfuscate($msg, $key)) . "\n";
print "deObfuscated: " . obfuscate(obfuscate($msg, $key), $key);


function obfuscate($msg, $key) {
    if (empty($key)) return $msg;
    return $msg ^ str_pad('', strlen($msg), $key);
}
于 2013-01-24T11:08:29.897 回答
3

我认为您可能在这里遇到一些问题,我试图概述我认为您可以如何解决它:

  • 您需要使用ord(..)来获取字符的 ASCII 值,以便您可以将其表示为二进制。例如,尝试以下操作:

    printf("%08b ", ord('A')); // outputs "01000001"
    
  • 我不确定您如何使用多字节密钥进行 XOR 密码,因为XOR 密码上的维基百科页面没有指定。但我假设对于像“123”这样的给定键,您的键开始“左对齐”并延伸到文本的长度,如下所示:

    function xor_this($text) {
        $key = '123';
        $i = 0;
        $encrypted = '';
        foreach (str_split($text) as $char) {
            $encrypted .= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
        }
        return $encrypted;
    }
    print xor_this('hello'); // outputs "YW_]]"
    

    其中加密'hello'宽度密钥'12312'

于 2011-09-25T21:49:58.560 回答
1

不能保证 XOR 操作的结果会产生可打印的字符。如果您让我们更好地了解您这样做的原因,我们可能会为您指出一些明智的做法。

于 2011-09-25T21:16:13.963 回答
1

我相信您面临的是控制台输出和编码问题,而不是与 XOR 相关的问题。尝试在文本文件中输出 xor 函数的结果并查看一组生成的字符。我相信 HEX 编辑器将是观察和比较生成的字符集的最佳选择。

基本上要恢复文本(偶数在),您可以使用相同的功能:

var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
于 2011-09-25T21:34:45.353 回答
1

基于你得到的事实xor_this( xor_this('123') ) = '123',我愿意猜测这只是一个输出问题。您正在向浏览器发送数据,浏览器将其识别为应该以 HTML 呈现的内容(例如,前半打 ASCII 字符)。尝试查看页面源代码以了解实际存在的内容。更好的是,遍历输出并回显ord每个位置的值。

于 2011-09-25T21:58:22.087 回答
1

使用此代码,它完美无缺

function scramble($inv) {
  $key=342244;  // scramble key
  $invarr=str_split($inv);
  for($index=0;$index<=strlen($inv)-1;$index++) {
    srand($key);
    $var=rand(0,255);
    $res=$res.(chr(ord($var)) ^ chr(ord($invarr[$index])));
    $key++;
  }
  return($res);
}
于 2014-03-13T14:48:24.947 回答
0

试试这个:

$outText .= (string)$text{$i} ^ (string)$key{$j};

如果两个操作数之一是整数,PHP 将另一个转换为整数并对它们进行异或运算以获得数值结果。

或者,你可以使用这个:

$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
于 2011-09-25T21:45:09.467 回答
0
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
    $outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}

注意:它可能会创建一些奇怪的字符...

于 2011-09-25T21:51:21.217 回答
-3

尽管有所有明智的建议,我还是以更简单的方式解决了这个问题:

我换了钥匙!事实证明,通过将密钥更改为更像这样的东西:

$key = 'ISINUS0478331006';

...它将生成可打印字符的混淆输出。

于 2011-09-29T13:41:40.670 回答