Need help ensuring text shifted 'x' amount of spaces is transformed into letters, not random symbols

戏子无情 提交于 2019-12-20 07:48:21

问题


I'm working on a page on cryptography, and have decided to include a Caesar Cipher, a method in which you shift a letter 'X' amount of spaces left or right. Example: Encrypting the letter 'A' with a shift parameter of 2. A => C.

The code below is working somewhat decently. It's able to encrypt/decrypt the text I enter, as long as it's between certain ASCII values.

The values 65-90 in ASCII is uppercase letters, and 97-122 is lowercase letters. My problem is if my shift parameter is so large, that I exceed these intervals.

Let's say I have the letter 'A' which I want to encrypt with a shift parameter of 100. If I try this, the letter 'A' becomes this character (http://www.theasciicode.com.ar/ascii-codes/spanish-enye-capital-letter-n-tilde-enie-uppercase-ascii-code-165.gif), which can't show up in my browser, and is converted into a weird question mark.

My question is, what are my options for avoiding these weird symbols? Is it possible to make it so it only includes letters (uppercase and lowercase) and maybe numbers as well?

I hope you can help me. I will be online all day, so if you need any more information, just ask :-)

My form field:

<form method="post">
<input type="text" name="textCaesarEncrypt" autocomplete="off" placeholder="Indtast tekst">
<input type="number" name="shiftCaesarEncrypt" autocomplete="off">
<label>Krypter</label>
<input type="radio" name="caesarEncryptOrDecrypt" value="caesarEncrypt">
<label>Dekrypter</label>
<input type="radio" name="caesarEncryptOrDecrypt" value="caesarDecrypt">
<input type="submit" name="submitCaesarEncrypt" value="Videre">

My PHP:

    <?php
        $caesarEncryptOrDecrypt = $_POST ["caesarEncryptOrDecrypt"];

     if (!empty($_POST['textCaesarEncrypt']) AND 
     !empty($_POST['shiftCaesarEncrypt'])){

$string = $_POST['textCaesarEncrypt'];
$shift = $_POST['shiftCaesarEncrypt'];
$shiftedString = "";


if($caesarEncryptOrDecrypt == "caesarEncrypt") {
    for ($i = 0; $i < strlen($string); $i++) {
        $ascii = ord($string[$i]);
        $shiftedChar = chr($ascii + $shift);

        $shiftedString .= $shiftedChar;
    }
    echo $shiftedString;
}

if($caesarEncryptOrDecrypt == "caesarDecrypt") {
    for ($i = 0; $i < strlen($string); $i++) {
        $ascii = ord($string[$i]);
        $shiftedChar = chr($ascii - $shift);

        $shiftedString .= $shiftedChar;
    }
    echo $shiftedString;


}

}   
?>

回答1:


First of all, it's important to mention that Caesar-Cipher is not recommended, it's too weak, weak, weak, too weak and pretty easy to be broken.

for sure you don't want to use an encrypting system which was used before more that 2000 years

Julius Caesar: 13 July 100 BC – 15 March 44 BC)


However, The key here is in the up next formula -in the encrypting case-:

while to decrypt your encrypted data , you will need to use the next formula :

where En(x) refers to encrypted char, x = char, n = shift value;

formulas images source [wikipedia]


However this formula is pretty good for humans, but not for computers , humans only have 26 Latin character, while computers have ASCII which represented by 128, also we don't care about the case of the letter, so Hello = heLLo for us, while it is not the same with computers which represents a as 97 and A as 65.

so you will need to convert your ASCII to easy 1-26 range of character.

here i will implement a simple edit in your encrypting part, and I hope that helps you to implement the rest of decrypting part of your code.

for ($i = 0, $n = strlen($string); $i < $n; $i++) {
    $char = $string[$i];
    // here we are checking the character type
    // to set the range which will be used later
    if (ctype_upper($char)) {
        $range = 65;
    } else if (ctype_lower($char)) {
        $range = 97;
    }
    // convert the ascii indexed chars into alphabetic indexed chars
    $ascii = ord($char) - $range;
    // the caesar folrmula based on alphabetic indexed chars
    $shiftedChar = chr((($ascii + $shift) % 26) + $range);
    $shiftedString .= $shiftedChar;
}
echo $shiftedString;

If you want to make sure that only alphabetic characters will be encoded, you may use ctype_alpha to check that, it's returns true if the character is alphabetic chars.

It's also important to notice that in decrypting Caesar-cipher , you will need as mentioned before to use the next formula :

$shiftedChar = chr((($ascii - $shift) % 26) + $range);
//                          ^ notice this

also to change your ranges as follows :

if (ctype_upper($char)) {
    $range = 90; // start with Z
} else if (ctype_lower($char)) {
    $range = 122; // start with z
}

another great helpful source from cs50 , this is a Caesar-cipher C tutorial , but it has the same concept.



来源:https://stackoverflow.com/questions/43651083/need-help-ensuring-text-shifted-x-amount-of-spaces-is-transformed-into-letters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!