Jump to content

Odd str_replace()


Henaro

Recommended Posts

Hello everyone~

 

My friend made a php file that decrypts data strings.  He sent it to me and I decided to make an encrypter.  Ithought to myself, "Why not just do what he did but backwards?"

 

Well I did and here's what I got:

 

<?php
//Data Key
$ddk = $_POST["decrypt"];

//add a space between each character
$n_ddk=chunk_split($ddk, 1);

//Encrypted characters array
$nec = array("32", "31", "30", "37", "36", "35", "34", "3b", "3a", "39", "38", "3f", "3e", "3d", "3c",
"23", "22", "21", "20", "27", "26", "25", "24", "2b", "2a", "29",
"12", "11", "10", "17", "16", "15", "14", "1b", "1a", "19", "18", "1f", "1e", "1d", "1c", "03", "02",
"01", "00", "07", "06", "05", "04", "0b", "0a", "09",
"62", "61", "60", "67", "66", "65", "64", "6b", "6a", "63", 
"0e", "08", "2f", "7c", "7e", 
"69", "6e", "7d", "2d", "0c",
"72", "13", "70", "77", "76", "0d", "75", "79", "73");

//Non encrypted characters array
$ec = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
"]", "[", "|", "/", "-",
":", "=", ".", "~", "_",
"!", "@", "#", "$", "%", "^", "&", "*", "(SPACE)");


//Encrypt
$e2n = str_replace($ec, $nec, $n_ddk);
?>

 

It works fine it's just that it adds 656 in front of every letter of the encryption.  Example:

Original:

hi

Encrypted:

6563b 6563a

 

Thanks,

Henaro

Link to comment
Share on other sites

str_replace() called with an array calls each substitution in sequence.  Here's an example

 

$input = '1';
$search = array(
  '1',
  '2',
);
$replace = array(
  '2',
  '3',
);
$output = str_replace($search, $replace, $input);
print "$output\n";

 

Notice that the 1 gets replaced by 2, and then replaced again by 3.  That's because the second replace is applied to the output of the first replace.  You might want to try strtr() instead.  From the manual:

 

"strtr() will always look for the longest possible match first and will *NOT* try to replace stuff that it has already worked on."

Link to comment
Share on other sites

This doesn't seem to work at all.  My friend used str_replace(); on his code and it works.  Infact his looks exactly like mine except for minor differences and it works.  This is his:

 

<?php
//Data Key
$ddk = $_POST["decrypt"];

$n_ddk=chunk_split($ddk, 2);

//Non encrypted characters array
$nec = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",  
"R", "S", "T", "U", "V", "W", "X", "Y", "Z", 
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", 
"]", "[", "|", "/", "-", 
":", "=", ".", "~", "_", 
"!", "@", "#", "$", "%", "^", "&", "*", "(SPACE)");

//Encrypted characters array
$ec = array("32", "31", "30", "37", "36", "35", "34", "3b", "3a", "39", "38", "3f", "3e", "3d", "3c",
"23", "22", "21", "20", "27", "26", "25", "24", "2b", "2a", "29", 
"12", "11", "10", "17", "16", "15", "14", "1b", "1a", "19", "18", "1f", "1e", "1d", "1c", "03", "02",  
"01", "00", "07", "06", "05", "04", "0b", "0a", "09", 
"62", "61", "60", "67", "66", "65", "64", "6b", "6a", "63", 
"0e", "08", "2f", "7c", "7e", 
"69", "6e", "7d", "2d", "0c", 
"72", "13", "70", "77", "76", "0d", "75", "79", "73");

//Decryption
$e2n = str_replace($ec, $nec, $n_ddk);
?>

Link to comment
Share on other sites

That's because he's exploting the fact that the encoded characters are all 2 characters long, but the decoded ones are all one character.  That means that the single decoded characters will never match on one of the later runs.  That's why he used chunk_pslit().

 

In your case, you are encoding one character into 2 chracters, so your encoded characters WILL match decoded characters.  You can't use his method.

 

You can fix it by reading the manual for strtr() and having your code use that.  You will have to convert the decryption table though.

 

$strtr_table = array();
$len = count($nec);
for ($i = 0; $i < $len; $i++) {
  $strtr_table[$ec[$i]] = $nec[$i];
}

 

That ought to work (not tested)

Link to comment
Share on other sites

Here's a bit more explanation for your original example

 

1.  "hi"

2.  "3bi" (h => 3b)

3.  "3b3a" (i => 3a)

4.  "60b60a" (3 => 60)

5.  "650b650a" (6 => 65)

6.  "6563b6563a" (0 => 63)

 

You see, each rule is being applied in turn, not all at the same time.  So you are getting multiple encryptions applied, resulting in the strange result string.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.