PHP 中数字的移位密码
Shift Cipher on numbers in PHP
我正在 php 中编写 vigenere 和移位密码的组合,其中,对于字符,它使用 vigenere table,对于数字,它使用提交的密钥的长度。它的加密很好,但是当我解密它时,数字只是 ????或 000s,这是数字部分的代码。
此外,如果键的长度超过 10,它只会给我类似“>”或“:”的值
$str = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1555s";
$key = "aaa";
printf("Text: %s\n", $str);
echo "<br> </br>";
printf("key: %s\n", $key);
$cod = encipher($str, $key, true);
$dec = encipher($cod, $key, false);
echo "<pre> Code:" . $cod . "</pre>";
echo "<pre> Back:" . $dec . "</pre>";
function encipher($src, $key, $encoder)
{
$key = strtoupper($key);
$src = strtoupper($src);
$dest = '';
/* strips out non-letters */
for($i = 0; $i <= strlen($src); $i++) {
$char = substr($src, $i, 1);
if(ctype_upper($char) or ctype_digit($char)) {
$dest .= $char;
}
}
for($i = 0; $i <= strlen($dest); $i++) {
$char = substr($dest, $i, 1);
if(ctype_digit($char)){
$dest = substr_replace($dest,
$encoder
? $char + strlen($key)
: $char - strlen($key)
, $i, 1);
}
if(!ctype_upper($char)) {
continue;
}
$dest = substr_replace($dest,
chr (
ord('A') +
($encoder
? ord($char) - ord('A') + ord($key[$i % strlen($key)]) - ord('A')
: ord($char) - ord($key[$i % strlen($key)]) + 26
) % 26
)
, $i, 1);
}
return $dest;
}
所以,输出是这样的
Code:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE4888S
Back:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE����S
但是,应该是这个
Code:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE4888S
Back:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE1555S
编辑:
它现在可以工作了,我更改了那里的代码,但是,如果键的长度使数字超过 10,它将超时
Fatal error: Maximum execution time of 30 seconds exceeded
您的示例中的密钥长度是多少?
如果在代码中回显 $char、ord($char) 和 strlen($key) 的值,您会看到什么?
(P.S。这是学术问题还是编程工作测试?这不是工作,是吗?)
我通过简单地创建一个从 0 到 9 的圆来修复它,如果它 >= 10,只需选择字符串的最后一个数字,然后使用数组的最后一个数字解密,将它添加到 90,所以如果数字是 5,辅助字符串将是 95 并减去它的密钥长度,只取它的最后一位,所以 95-6 = 9.
数字循环encryption/decryption:
for ($i = 0; $i <= strlen($dest); $i++) {
$char = substr($dest, $i, 1);
if (ctype_digit($char)) {
$aux = array(9,0);
$aux[1]=$char;
$dest = substr_replace($dest,
$encoder
? str_split($char + strlen($key))[(strlen($char + strlen($key))-1)]
: str_split(implode($aux)-strlen($key))[1]
, $i, 1);
}
我正在 php 中编写 vigenere 和移位密码的组合,其中,对于字符,它使用 vigenere table,对于数字,它使用提交的密钥的长度。它的加密很好,但是当我解密它时,数字只是 ????或 000s,这是数字部分的代码。
此外,如果键的长度超过 10,它只会给我类似“>”或“:”的值
$str = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1555s";
$key = "aaa";
printf("Text: %s\n", $str);
echo "<br> </br>";
printf("key: %s\n", $key);
$cod = encipher($str, $key, true);
$dec = encipher($cod, $key, false);
echo "<pre> Code:" . $cod . "</pre>";
echo "<pre> Back:" . $dec . "</pre>";
function encipher($src, $key, $encoder)
{
$key = strtoupper($key);
$src = strtoupper($src);
$dest = '';
/* strips out non-letters */
for($i = 0; $i <= strlen($src); $i++) {
$char = substr($src, $i, 1);
if(ctype_upper($char) or ctype_digit($char)) {
$dest .= $char;
}
}
for($i = 0; $i <= strlen($dest); $i++) {
$char = substr($dest, $i, 1);
if(ctype_digit($char)){
$dest = substr_replace($dest,
$encoder
? $char + strlen($key)
: $char - strlen($key)
, $i, 1);
}
if(!ctype_upper($char)) {
continue;
}
$dest = substr_replace($dest,
chr (
ord('A') +
($encoder
? ord($char) - ord('A') + ord($key[$i % strlen($key)]) - ord('A')
: ord($char) - ord($key[$i % strlen($key)]) + 26
) % 26
)
, $i, 1);
}
return $dest;
}
所以,输出是这样的
Code:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE4888S
Back:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE����S
但是,应该是这个
Code:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE4888S
Back:LOREMIPSUMISSIMPLYDUMMYTEXTOFTHEPRINTINGANDTYPESETTINGINDUSTRYLOREMIPSUMHASBEENTHEINDUSTRYSSTANDARDDUMMYTEXTEVERSINCETHE1555S
编辑:
它现在可以工作了,我更改了那里的代码,但是,如果键的长度使数字超过 10,它将超时
Fatal error: Maximum execution time of 30 seconds exceeded
您的示例中的密钥长度是多少?
如果在代码中回显 $char、ord($char) 和 strlen($key) 的值,您会看到什么?
(P.S。这是学术问题还是编程工作测试?这不是工作,是吗?)
我通过简单地创建一个从 0 到 9 的圆来修复它,如果它 >= 10,只需选择字符串的最后一个数字,然后使用数组的最后一个数字解密,将它添加到 90,所以如果数字是 5,辅助字符串将是 95 并减去它的密钥长度,只取它的最后一位,所以 95-6 = 9.
数字循环encryption/decryption:
for ($i = 0; $i <= strlen($dest); $i++) {
$char = substr($dest, $i, 1);
if (ctype_digit($char)) {
$aux = array(9,0);
$aux[1]=$char;
$dest = substr_replace($dest,
$encoder
? str_split($char + strlen($key))[(strlen($char + strlen($key))-1)]
: str_split(implode($aux)-strlen($key))[1]
, $i, 1);
}