Hello so i have this encode/decode script

<?php

// Encoding key
$key = "vns98ogavna5489hverz9np950yhz9gzx89fghjv9pv4598hj";

function encode($string,$key) {
    $key = sha1($key);
    $strLen = strlen($string);
    $keyLen = strlen($key);
    for ($i = 0; $i < $strLen; $i++) {
        $ordStr = ord(substr($string,$i,1));
        if ($j == $keyLen) { $j = 0; }
        $ordKey = ord(substr($key,$j,1));
        $j++;
        $hash .= strrev(base_convert(dechex($ordStr + $ordKey),16,36));
    }
    return $hash;
}

function decode($string,$key) {
    $key = sha1($key);
    $strLen = strlen($string);
    $keyLen = strlen($key);
    for ($i = 0; $i < $strLen; $i+=2) {
        $ordStr = hexdec(base_convert(strrev(substr($string,$i,2)),36,16));
        if ($j == $keyLen) { $j = 0; }
        $ordKey = ord(substr($key,$j,1));
        $j++;
        $hash .= chr($ordStr - $ordKey);
    }
    return $hash;
}

?>

so what i am trying to do is grab a file and decode the 2nd and 3rd words only of each line.
There is 4 words per line. This is the script i made to remove the first line and remove the first and last words on each sentence. Then print the page, all which works well. the problem i am having is to decode the remaining words all at once.

<?php
// removes the first line 
   $hideStartWith = "<";
   $replaceWith = "";
   $file = "./pass_users.php";
   $f = fopen($file, "r");
   while ( $line = fgets($f, 1000) ) {
          if(substr($line, 0, strlen($hideStartWith)) === $hideStartWith){
                 $line = $replaceWith;  
         }
// replace word      
         $test = str_replace("||","&nbsp &nbsp &nbsp &nbsp",$line);

// removes last word in string

$b = preg_replace('~\\s+\\S+$~', '', $test);

// removes first word in string

         $q = substr(strstr($b," "), 1);
print nl2br($q);
   }
?>

i can decode single words just fine.
example

Encode:
<?php echo encode("Please Encode Me!","This is a key"); ?>

Result:
p3e4e4241674d2r4m4i5o464a4f2p3k5c2


Decode:
<?php echo decode("p3e4e4241674d2r4m4i5o464a4f2p3k5c2","This is a key"); ?>

Result:
Please Encode Me!

Thank you

By collecting all the remaining words (second & third of each line) into an array you could loop it against the decoding function. If in doubt, please, provide an example of encoded file.

thanks so much cereal for the reply, i think i understand what you mean however i can not seem to get it to work. so here is an example encoded file

16e4o4y5b2 16e4o4y5b2
j5o474 j5o474
64z2w264v2a4n484n5b4 64z2w264v2a4n484n5b4

Ok, I was thinking to something like this:

<?php

    require 'functions.php';

    $result = '';
    $file   = file('encoded.txt');

    foreach($file as $line)
    {
        $array = explode(' ', $line);

        array_shift($array);
        array_pop($array);

        $convert = array_map(function($value) use($key){
            return decode($value, $key);
        }, $array);

        $result .= implode(' ', $convert) . PHP_EOL;
    }

    echo $result;

The file() function reads each line of the source into an array, then we loop and explode each line (which is still a string), then array_shift() and array_pop() will remove the first and the last element of the line array, leaving only the two central elements in the array which are looped against the decode() function through array_map() (which is faster than a simple loop) and an anonymous function.

Normally, you could call directly your decode function, but the second argument of your function is the decoding key which is always the same, so in order to work properly you should create another array where you repeat such value, as array_map does not support strings:

foreach($file as $line)
{
    $array = explode(' ', $line);

    array_shift($array);
    array_pop($array);

    $keys[]  = $key;
    $convert = array_map('decode', $array, $keys);

    $result .= implode(' ', $convert) . PHP_EOL;
}

Which is not much memory efficient if you're going to decode a large number of strings.

And, to use fopen() just replace $file and the foreach statement with this:

$file   = fopen('encoded.txt', 'r');
while($line = fgets($file, 1000))

I would just like to understand if you want to skip the first line. From your previous code it seemed that it was your intention, but your encoded example was simple. In that case you could simply skip the first loop:

# outside the loop
$i = FALSE;

while(...)
{
    if($i === FALSE)
    {
        $i = TRUE;

        # skip
        continue;
    }

    # code here...
}

Besides, both your functions are spitting few notices about undeclared variables, simply set them before the for loop:

$j = 0;
$hash = '';

And it will be fixed.

thanks cereal but this code returns nothing on the echo. am i doing this wrong ?

  <?php
        require 'functions.php';
        $result = '';
        $file   = file('encoded.txt');
        foreach($file as $line)
        {
            $array = explode(' ', $line);
            array_shift($array);
            array_pop($array);
            $convert = array_map(function($value) use($key){
                return decode($value, $key);
            }, $array);
            $result .= implode(' ', $convert) . PHP_EOL;
        }
        echo $result;

            foreach($file as $line)
    {
        $array = explode(' ', $line);
        array_shift($array);
        array_pop($array);
        $keys[]  = $key;
        $convert = array_map('decode', $array, $keys);
        $result .= implode(' ', $convert) . PHP_EOL;
    }
        ?>

thanks

No problem! So, it seems to work fine for me. Maybe the path to the encoded file is not correct or readable by the PHP script? Here's my live test:

I'm encoding and saving the input to a temporary file, then using the result for the decoding test, the decoding block is practically the same of my & yours previous post. Just click run and test it. As basic input, with $key = 'test' you should get:

Input
a b c d

Encoded
e5 f5 g5 h5

Decoded
b c

In my tests, I got an empty result only when the source file was not found, due to read permissions or wrong path.

If this does not help, try to change the error reporting level to -1:

error_reporting(-1);

to return all errors.

Member Avatar for diafol

Nice work. Use file_exists() to check before doing the 'read'.

nice thank you !
special chacters are separating words.

example:
1 admin admin@gmail.com password
2 bob bob@gmail.com bobpass

result
Decoded

admin gmail
bob bob

how would i do this, the result im looking for is
Decoded

admin admin@gmail.com
bob bob@gmail.com

thanks again for your help, people like you are why i love this site.

Member Avatar for diafol

Split on space and re-join first two elements:

$bits = explode(' ', $raw);
array_pop($bits);
$decoded = implode(' ', $bits);

Perhaps easier way. Will think.

//EDIT - this maybe?

$decoded = substr( $raw, 0, strrpos($raw, ' ') );

In addition: the example code does not take in account special characters, but these can be added to str_word_count() as third parameter, at line 19:

$words  = str_word_count($post, 1, '@.-_0123456789');

If you want to use this approach, then you should include all allowed special characters to the list, otherwise the function will split or ignore. The example is now updated and should return correctly.

thanks guys
cereal

admin admin@gmail.com
bob bob@gmail.com

returns as

Decoded

admin admin@gmail.com
10 2

thanks

That's due to new lines \n (10 in ascii code) or carriage returns \r (13) or other characters (null bytes) in the textarea of the example form.

The sanitize filter FILTER_SANITIZE_SPECIAL_CHARS of filter_var() was converting them, I replaced that with FILTER_SANITIZE_STRING and a trim() after line 14, now it should play fine.

Please, note that the example was developed just to send some random input and show how to decode adjacent strings, not as encode solution, that part is very limited and is breaking lines in groups of four words, just to create a dummy list to encode. So that you could enter the input as:

1 admin admin@gmail.com password 2 bob bob@gmail.com bobpass

Instead of using two lines. That part of script is written like this just because I entered loripsum.net API to get some random sentences to test... bye!

thank you

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.