PHP 中的异或加密

发布于 2024-12-06 13:39:28 字数 1003 浏览 1 评论 0原文

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

I'm new to Xor encryption, and I'm having some trouble with the following code:

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

When I run this it works for normal strings, like 'dog' but it only partially works for strings containing numbers, like '12345'.

To demonstrate...

xor_this('dog') = 'UYV'

xor_this('123') = ''

It's also interesting to note that xor_this( xor_this('123') ) = '123', as I expect it to. I'm pretty sure the problem resides somewhere in my shaky understanding of bitwise operators, OR possibly the way PHP handles strings that contain numbers. I'm betting there's someone clever out there that knows exactly what's wrong here. Thanks.

EDIT #1: It's not truly 'encryption'. I guess obfuscation is the correct term, which is what I'm doing. I need to pass a code containing unimportant data from a user without them being able to easily tamper with it. They're completing a timed activity off-line and submitting their time to an online scoreboard via this code. The off-line activity will obfuscate their time (in milliseconds). I need to write a script to receive this code and turn it back into the string containing their time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

橘虞初梦 2024-12-13 13:39:29

我是如何做到的,可能会帮助别人......

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

How i did it, might help someone ...

$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);
}
梦幻的心爱 2024-12-13 13:39:29

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

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

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

     函数 xor_this($text) {
         $key = '123';
         $i = 0;
         $加密 = '';
         foreach (str_split($text) as $char) {
             $加密.= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
         }
         返回$加密;
     }
     打印 xor_this('你好'); // 输出“YW_]]”
    

它加密'hello'宽度密钥“12312”。

I think you might have a few problems here, I've tried to outline how I think you can fix it:

  • You need to use ord(..) to get the ASCII value of a character so that you can represent it in binary. For example, try the following:

     printf("%08b ", ord('A')); // outputs "01000001"
    
  • I'm not sure how you do an XOR cipher with a multi-byte key, as the wikipedia page on XOR cipher doesn't specify. But I assume for a given key like "123", your key starts "left-aligned" and extends to the length of the text, like this:

     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_]]"
    

Which encrypts 'hello' width the key '12312'.

留蓝 2024-12-13 13:39:29

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

There's no guarantee that the result of the XOR operation will produce a printable character. If you give us a better idea of the reason you're doing this, we can probably point you to something sensible to do instead.

再浓的妆也掩不了殇 2024-12-13 13:39:29

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

基本上要恢复文本(甚至数字),您可以使用相同的函数:

var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);

I believe you are faced with console output and encoding problem rather than XOR-related.
Try to output results of xor function in a text file and see a set of generated characters. I believe HEX editor would be the best choice to observe and compare a generated characters set.

Basically to revert text back (even numbers are in) you can use the same function:

var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
柳若烟 2024-12-13 13:39:29

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

Based on the fact that you're getting xor_this( xor_this('123') ) = '123', I am willing to guess that this is merely an output issue. You're sending data to the browser, the browser is recognizing it as something which should be rendered in HTML (say, the first half dozen ASCII characters). Try looking at the page source to see what is really there. Better yet, iterate through the output and echo the ord of the value at each position.

活泼老夫 2024-12-13 13:39:29

使用此代码,效果完美

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);
}

Use this code, it works perfect

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);
}
御守 2024-12-13 13:39:29

试试这个:

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

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

或者,你可以使用这个:

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

Try this:

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

If one of the two operands is an integer, PHP casts the other to an integer and XORs them for a numeric result.

Alternatively, you could use this:

$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
恬淡成诗 2024-12-13 13:39:29
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
    $outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}

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

// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
    $outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}

note: it probably will create some weird characters...

梦在深巷 2024-12-13 13:39:29

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

我更改了密钥!事实证明,通过将密钥更改为类似这样的内容:

$key = 'ISINUS0478331006';

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

Despite all the wise suggestions, I solved this problem in a much simpler way:

I changed the key! It turns out that by changing the key to something more like this:

$key = 'ISINUS0478331006';

...it will generate an obfuscated output of printable characters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文