79711570

Date: 2025-07-23 08:57:01
Score: 2.5
Natty:
Report link

Important note regarding @Jorgeblom's algo:

BE WARNED!!! The text with @Jorgeblom is NOT "encrypted", but only "masked" due to the same pattern. Please do not be fooled by knotted script wordings and schematic shorthand notations! This does not necessarily make the algo more complex, nor make it more effective or faster - but quite the opposite: Separately declared variable-functions require unnecessary resources and additional management overhead and are often only intended to impress the layman - ridiculous!

If you break down the "arrow notation" into its components, you will find chained "split" and "merge" actions over several nested arrays, which also lead to unnecessary costs and delays in the program flow due to their constant rearrangements. At the end the core algorithm for encryption (that's the main topic here) only consists of a primitive XOR operation - nothing more!

The monstrous fuss can be reconstructed with two simple "for-next" loops, as you can see below - and you'll recognize all the nonsense immediately:

function crypt(salt, text) {
    // First, we assign a virgin output string:
    var output = "";
    // Then, we walk letter-wise through the given original text:
    for(var i = 0; i < text.length; i++){
        var val = text.charCodeAt(i);
        // Now we manipulate each letter value with a sum of "salt" XOR's.
        // This is absolutely stupid, because it repeats for every main-loop
        // the same sub-loop. So it gives each time also an identical XOR-sum
        // and retards the entire iteration extremely - just for nothing:
        for(var k = 0; k < salt.length; k++){
            val = val^(salt.charCodeAt(k));
        }
        // Append each XOR-result as 2-digit HEX-value to the output string:
        output += (val < 16 ? '0' : "") + val.toString(16);
    }
    // Return that very poor encrypted (let's say "masked") output:
    return output;
}

... surprisingly poor, isn't it? The second (nested) "for-next" loop is pointless because it always returns the same pattern and therefore always codes the same characters in the same way. This is why we can only speak of "masking" instead of "encrypting". A simple pattern comparison of the ciphers reveals frequently occurring identical letters on the spot.

As the matching XOR value does not change anyway during the entire sequence, the task can be solved very conveniently with my following, little helper function:

function hackThis(crypt) {
    // Try the max. amount of 256 XOR values (0 - 255) to decode the cipher.
    // The result are 256 text blocks and you have to check each (256 items are
    // manageable). I ASSURE: One of them is READABLE AND CORRECT DECRYPTED!!!
    for(var Xval = 0; Xval < 256; Xval++){
        // Convert each to an ASCI-Char. to be digestible for the "decrypt" algo:
        var Xstr = String.fromCharCode(Xval);
        // Call the decrypt algo with the questionable character as a "salt":
        var output = decrypt(Xstr, crypt);
        // List the test result on the screen:
        document.writeln('Nr.#'+('00'+Xval).slice(-3)+': ' + output + '<br>');
    }
}

... so easy! This "hack" works with any previously used password (no matter how complex), and is the doubt free evidence of the uselessness of the crypt algo described above.

However - please let me being constructive:

First, I use the code of each already encrypted character from the original text as an encryption basis for the next followed character. This method (see below) creates a "self-encryption" that is hard to evaluate from the outside.

The initial encryption is performed by using a "pseudo hash" of the password. I call it "pseudo" because only values from 0 to 255 can be considered due to the ASCII compatibility of the XOR results. This limitation causes another problem, which is addressed in the 2nd example further below. For a start, please take a look at my first example "selfCryptBasics":

function selfCryptBasics(orgtext, passphrase) {

    // First, assign some initial variables:
    var value, pseudoHash = 0, preVal = 0, orgLen = orgtext.length, output = "";

    // Force the "string" type of a possible numeric passphrase (assignment
    // of a different variable name is essential for a successful conversion):
    var cryptKey = String(passphrase);
    var cryptKeyLen = cryptKey.length;

    // Create a "pseudo hash" of the given crypt key (= pass phrase):
    for(var i = 0; i < cryptKeyLen; i++) {
        pseudoHash = pseudoHash^(cryptKey.charCodeAt(i));
    }

    // Walk letter-wise through the org. text and get their ASCI value:
    for(var i = 0; i < orgLen; i++){
        var value = orgtext.charCodeAt(i);

        // Double encrypt the current letter with 2 nested XOR operations.
        // The first XOR operator uses the "pseudo hash" and the second
        // the code value of the previously encrypted letter:
        value = (value^pseudoHash)^preVal;

        // Store the current code value temporarily for the next loop:
        preVal = value;

        // Append the XOR-result as 2-digit HEX-value to the output string:
        output += (value < 16 ? '0' : "") + value.toString(16);
    }

    // Return the encrypted output:
    return output;
}

You may try this example with the original text "stresslessness" and look at the code. There is 7 times the letter "s" and 3 times the letter "e" encoded but its hard to find equal ciphers of them - quite good, eh?!

But we have still that poor encryption problem via XOR values which can be easily evaluated with my "hack" script" above!!

I insist on XOR encryption because it is uncomplicated and extremely fast. Generating "real" hash codes with dozens of digits requires complex calculations and correspondingly expensive processing. However, if the original password is chopped up into pieces and "XOR'ed" individually, the sum of all the little keys results also in a nearly unique hash - so I did in my 3rd (and final) example:


function selfCrypt(orgtext, passphrase) {

    var value, preVal, cutPos = 0, tmpHash = 0, output = "";
    var pseudoHash = new Array(), orgLen = orgtext.length;
    var cryptKey=String(passphrase);
    var cryptKeyLen = cryptKey.length;

    // Create an array of different "pseudo hashes":
    // Therefore truncate the crypt key incrementally from left to right and
    // create a specific hash value for each version. In this way, we hope to
    // get significantly different values from the starting hash at each pass
    // (which is highly probable, except keys like "xxxx" or "0000" are used).
    for(var i = 0; i < cryptKeyLen; i++) {
        for(var k = cutPos; k < cryptKeyLen; k++) {
            tmpHash = tmpHash^(cryptKey.charCodeAt(k));
        }
        // Fill each hash version into a fast accessible array,
        // update the counter, and reset the temp. hash variable:
        pseudoHash.push(tmpHash);
        cutPos++;
        tmpHash = 0;
    }

    // Let the encryption begin!
    // To do this, the variable “cutPos” is used as a pointer for the
    // hash array. We start at the end of the array and jump back step by
    // step after each run.
    cutPos = cryptKeyLen;

    // Walk letter-wise through the org. text as usual:
    for(var i = 0; i < orgLen; i++){
        var value = orgtext.charCodeAt(i);

        // Double encrypt the letter like we did in the 1st example, but...
        // ...watch out: Instead one single "pseudo hash" we have now
        // varying values from the hash array on each loop:
        value = (value^pseudoHash[cutPos])^preVal;

        // Store the current code value temporarily for the next loop
        // and set the next lower pointer position. If the zero position
        // is reached, reset the pointer at it's end position:
        preVal = value;
        cutPos--;
        if (cutPos < 0) cutPos = cryptKeyLen;

        // Prepare the output string as usual:
        output += (value < 16 ? '0' : "") + value.toString(16);
    }
    // Return the encrypted output:
    return output;
}

The resulting code is almost impossible to crack, as it provides no external clues to any patterns. The algorithm presented here can be placed openly in any type of document without risk, as it is not the script itself that keeps the key, but only user's password and the self encrypting text!

...aah - you want to decode this scrambled stuff too??

OK, here we go:

function selfDecrypt(cipher, passphrase) {

    var value, memVal, preVal, cutPos = 0, tmpHash = 0, output = "";
    var pseudoHash = new Array(), cipherLen = cipher.length;
    var cryptKey = String(passphrase);
    var cryptKeyLen = cryptKey.length;

    // Generate the "pseudo hash" array:
    for(var i = 1; i < cryptKeyLen; i++) {
        for(var k = cutPos; k < cryptKeyLen; k++) {
            tmpHash = tmpHash^(cryptKey.charCodeAt(k));
        }
        pseudoHash.push(tmpHash);
        tmpHash = 0;
        cutPos++;
    }
    cutPos = cryptKeyLen;

    // Walk through the hex cipher in steps of 2 char's:
    for(var i=0; i<cipherLen; i+=2){
        // Get the decimal value of the current 2-digit hex:
        value = (parseInt(cipher.substring(i,i+2),16));

        // Hold this code value temporarily for the next decryption loop:
        memVal = value;

        // Decrypt the code with the double XOR algo:
        value = (value^pseudoHash[cutPos])^preVal;

        // Store the temp. hold original code for the next loop:
        preVal = memVal;

        // Update the control variables:
        cutPos--;
        if (cutPos < 0) cutPos = cryptKeyLen;

        // Convert the decoded value into a guilty ASCII-character
        // and append it to the output string:
        output += String.fromCharCode(value);
    }

    // Return the plain text:
    return output;
}

... that's it!

Due to its simple structure and the widely known commands, this script can be easily translated into other program languages (e.g. PHP, Phyton or even VBA)!

Have fun and a nice day!

P.S.:

Hash codes always come with a "collision risk", which means two different passwords might accidentally generate the same hash. This very vague risk could also occur with my "pseudo" hashes, but is even less likely, as this method always uses different lengths of the original password. It may be that some sections generate identical hashes, but in their sum as an array chain, this will hardly be the case. Alan Turing's "bomb" would be suitable for detecting such collisions - but who has such a loud, huge thing lying around their basement? ;-)

Reasons:
  • Whitelisted phrase (-1): try this
  • RegEx Blacklisted phrase (2.5): please let me
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
  • User mentioned (1): @Jorgeblom's
  • User mentioned (0): @Jorgeblom
  • Low reputation (1):
Posted by: ejomi