Home-grown encryption/decryption function I know what you are thinking, it's never a good idea to roll your own encryption functions, but I'm doing this for fun and self-learning.

I created a function that allows you to send a string as a parameter and it will return an encrypted version of the string.

Here is my encryption function:

function encrypt($string) {
    $characters = str_split($string);
    foreach($characters as &amp;$character) {
        $ascii = ord($character);
        $random = rand(0,9);
        if($ascii &lt; 44) {
            $prefix = chr(rand(35,78));
            $letter = chr($ascii + $random);
        } else {
            $prefix = chr(rand(79,122));
            $letter = chr($ascii - $random);
        }
        $r_ascii = [chr(rand(35,122)), chr(rand(35,122)), chr(rand(35,122))];
        $character = "{$prefix}{$random}{$r_ascii[0]}{$letter}{$r_ascii[1]}{$r_ascii[2]}";
    }
    return implode("", $characters);
}


This will encrypt the string, whereas every character will become 6 characters. The 1st 2 of each character are keys that are required to decrypt the letter, and the 4th character is the actual character being encrypted except masked by a random digit (Basically the letter is converted to its ASCII number and a random number between 0-9 is added/subtracted from the letter). The 1st key (labeled prefix) lets the decrypt function know if the random number needs to be added or subtracted, the random number is passed as the 2nd character in the encryption, and characters 3, 5 and 6 are random noise characters.

Note: The prefix is generated depending on the ASCII number of the character that is being encrypted. If this ASCII number is below 44, the random number is always added to the character being encrypted, else it is always subtracted. The prefix itself is a character in a certain range, if the ASCII number is below 44, a random character between ASCII 35 and 78 is generated, any of these characters tell the decrypt function to subtract the random number from the encrypted character, else ASCII between 79 and 122 will always add the number.

For example, the string "Never roll your own encryption functions." may encrypt to:

s7uGsxW0ueMkX99m^Zr6E_3jP1cqJ_&gt;67&amp;KyX6jlX.k7@hb/m1BkFDQ94cD7&lt;0: c$`9Zp3ot6*iHLW2.sSsm2YpZ,=00 4zW3Tl\ti5@r4ir2]l&lt;791H!9'f3ebw0y8ef%1a7B\&gt;)u2_pY)s4qu0-[1ZoRRv6)nIn\2kgx?n9df@&amp;j8sfP8#9))p1z1JejRd9Hl(t[27l+9R5y^&gt;GT0&amp;tu\w2]gAif8ig;AZ3mkf@Q7Yl#/h86&amp;np


Now, the decrypt function:

function decrypt($string) {
    $characters = str_split($string, 6);
    foreach($characters as &amp;$character) {
        if(strlen($character) &gt; 6) continue;
        $parts = str_split($character);
        if(ord($parts[0]) &gt; 78) {
            $character = chr(ord($parts[3])+$parts[1]);
        } else {
            $character = chr(ord($parts[3])-$parts[1]);
        }
    }
    return implode("", $characters);
}


This function takes the encrypted string and breaks it into parts of 6 (Because every encrypted character is equal to 6 characters) and reverses all of the randomizations that I did during encryption to return the string:

Never roll your own encryption functions.




My question(s): What shortcomings will I have with these functions?

Another question I have is; how can these functions be improved?
The main shortcoming of this algorithm is that it relies solely on security through obscurity. 

Since you save all information to reconstruct the plain-text string in the encrypted string, the only information keeping that encrypted string safe is the fact that an attacker has to know how to get the decrypted string from it. This is inherently unsafe.



As an attacker (who does not know the algorithm, but can use the encrypt function), one could note the following features:


The encrypted string is always six times longer than the plain-text, so a good guess would be that each block of six characters encodes one character.
The second character of that block is always a number, so it is probably not a function that transforms a single character to six random looking characters.
At this point it becomes a game of finding correlations between the characters in the encrypted string and the plain text. A common strategy would be seeing which offset would be needed to get a certain character in the encrypted string. This would lead to the finding that the offset is actually in the encrypted string and your "encryption" is broken.