PHP rot13与ASCII

时间:2018-09-30 02:41:05

标签: php encoding

我想用rot13进行简单的加密,但是我不想使用功能str_rot13(),因为我想在上面加上数字,并且我认为不支持str_rot13()。 我已经找到了这样的代码并想要进行编辑,但是我不知道如何

<?php 

$string = "Hello World 123";

for ($i = 0, $j = strlen( $string); $i < $j; $i++) 
{
    // Get the ASCII character for the current character
    $char = ord( $string[$i]); 


    // If that character is in the range A-Z or a-z, add 13 to its ASCII value
    if( ($char >= 65  && $char <= 90) || ($char >= 97 && $char <= 122)) 
    {
        $char += 13; 

        // If we should have wrapped around the alphabet, subtract 26
        if( $char > 122 || ( $char > 90 && ord( $string[$i]) < 97)) 
        {
            $char -= 26;
        }
    }
    echo chr( $char);
}

 ?>

此代码的结果为“ Uryyb Jbeyq 123”。我想要的是在上面加上数字0-9,这样加密就变成rot18-> a-z0123456789。结果成为“ Zw336 E693v JKL”

1 个答案:

答案 0 :(得分:0)

Str_rot13是一种编码解码功能,表示str_rot13(str_rot13('some string here'))==='some string here'。根据我的说法,构建此类功能的最有效方法是使用简单的内部映射。在PHP中,我们可以使用从1开始索引的数组至36而不是使用ASCII代码来实现。使用ASCII码,您将面临难以轻松实现编码解码功能的困难,因此您的算法将变得不那么快。下面是上述str_rot18编码解码功能的基本实现:

 function str_rot18($string){
    if(!is_string($string)) return false; 
    $map=array (
      'a' => 1, 'b' => 2,'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6,'g' => 7,'h' => 8,
      'i' => 9,
      'j' => 10,'k' => 11,'l' => 12,'m' => 13,'n' => 14,'o' => 15,'p' => 16,'q' => 17,
      'r' => 18,
      's' => 19,'t' => 20, 'u' => 21,'v' => 22,'w' => 23,'x' => 24,'y' => 25,'z' => 26,
       0 => 27,1 => 28,2 => 29,3 => 30,4 => 31,5 => 32,6 => 33,7 => 34,8 => 35,9 => 36,
    );
    $flipped_map=array (
      1 => 'a',2 => 'b',3 => 'c',4 => 'd',5 => 'e',6 => 'f',7 => 'g',8 => 'h',9 => 'i',
      10 => 'j',11 => 'k',12 => 'l',13 => 'm',14 => 'n',15 => 'o',16 => 'p',17 => 'q',
      18 => 'r',19 => 's',20 => 't',21 => 'u',22 => 'v',23 => 'w',24 => 'x',25 => 'y',
      26 => 'z',27 => 0,28 => 1,29 => 2,30 => 3,31 => 4,32 => 5,33 => 6,34 => 7,35 => 8,
      36 => 9,
    );

    for ($i = 0, $j = strlen( $string); $i < $j; $i++) 
    {
        if(!ctype_digit($string[$i])){
            $char=mb_strtolower($string[$i]);
        }
        else $char=(int)$string[$i];

        if(isset($map[$char])){
            $tmp = $map[$char]+18; 
            $tmp=($tmp>36)?$tmp-36:$tmp;
            if(!ctype_lower($string[$i])&&!ctype_digit($string[$i]))
                $string[$i]=mb_strtoupper($flipped_map[$tmp]);
            else
                $string[$i]=$flipped_map[$tmp];
        }
    }
    return $string;
}

当然可以改进,但这已经是一个很好的起点...

但是如果您真的想使用ASCII代码,我建议使用完整的ASCII映射以允许所有字符并保持快速,易于实现的编码解码功能的精神。因此,您的功能将是str_rot128而不是str_rot18

function str_rot128($string){
    if(!is_string($string)) return false; 
    for ($i = 0, $j = strlen( $string); $i < $j; $i++) 
    {
        // Get the ASCII character for the current character
        $char=ord($string[$i])+128;
        $char=$char>256?$char-256:$char;
        $string[$i]=chr($char); 
    }
    return $string;
}

您可以在此处看到有效的代码: Alternative to str_rot13 using more characters than a-z