I need to XOR a string/text in PHP the base64 encode it, but something goes wrong:
<?php
$mustget = 'Kw4SCQ==';
$string = 'Josh';
echo("Must get: " . $mustget . "\n");
echo("We got: " . base64_encode(xor_this($string)) . "\n");
function xor_this($text) {
$key = 'frtkj';
$i = 0;
$encrypted = '';
foreach (str_split($text) as $char) {
$encrypted .= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
}
return $encrypted;
}
?>
I get the following result, but I need to get the "$mustget" one:
Must get: Kw4SCQ==
We got: LB0HAw==
What do I do wrong?
$mustget = 'Kw4SCQ==';
$key = 'frtkj';
$key_length = strlen($key);
$encoded_data = base64_decode($mustget);
$result = '';
$length = strlen($encoded_data);
for ($i = 0; $i < $length; $i++) {
$tmp = $encoded_data[$i];
for ($j = 0; $j < $key_length; $j++) {
$tmp = chr(ord($tmp) ^ ord($key[$j]));
}
$result .= $tmp;
}
echo $result; // Josh
http://ideone.com/NSIe7K
I'm sure you can reverse it and create a function, that "crypts" the data ;-)
Related
I need to convert a large collection of binary to a string.
The code I used to get the binary code is:
$buffer = file_get_contents('test.php');
$length = filesize('test.php');
if (!$buffer || !$length) {
die("Reading error\n");
}
$_buffer = '';
for ($i = 0; $i < $length; $i++) {
$_buffer .= sprintf("%08b", ord($buffer[$i]));
}
I tried to use base_convert().This gives my the following error message :
<?php
pack('H*', base_convert($_buffer , 2, 16));
?>
Warning: base_convert(): Number too large in
C:\xampp\htdocs\decrypt.php on line 25
Any suggestions?
The binary code is
0011110000111111011100000110100001110000000011010000101000100100011000100111010101100110011001100110010101110010001000000011110100100000011001100110100101101100011001010101111101100111011001010111010001011111011000110110111101101110011101000110010101101110011101000111001100101000001001110111010001100101011100110111010000101110011100000110100001110000001001110010100100111011000011010000101000100100011011000110010101101110011001110111010001101000001000000011110100100000011001100110100101101100011001010111001101101001011110100110010100101000001001110111010001100101011100110111010000101110011100000110100001110000001001110010100100111011000011010000101000001101000010100110100101100110001000000010100000100001001001000110001001110101011001100110011001100101011100100010000001111100011111000010000000100001001001000110110001100101011011100110011101110100011010000010100100100000011110110000110100001010001000000010000001100100011010010110010100101000001000100101001001100101011000010110010001101001011011100110011100100000011001010111001001110010011011110111001001011100011011100010001000101001001110110000110100001010011111010000110100001010000011010000101000100100010111110110001001110101011001100110011001100101011100100010000000111101001000000010011100100111001110110000110100001010011001100110111101110010001000000010100000100100011010010010000000111101001000000011000000111011001000000010010001101001001000000011110000100000001001000110110001100101011011100110011101110100011010000011101100100000001001000110100100101011001010110010100100100000011110110000110100001010001000000010000000100100010111110110001001110101011001100110011001100101011100100010000000101110001111010010000001110011011100000111001001101001011011100111010001100110001010000010001000100101001100000011100001100010001000100010110000100000011011110111001001100100001010000010010001100010011101010110011001100110011001010111001001011011001001000110100101011101001010010010100100111011000011010000101001111101000011010000101001100101011000110110100001101111001000000111000001100001011000110110101100101000001001110100100000101010001001110010110001100010011000010111001101100101010111110110001101101111011011100111011001100101011100100111010000101000001001000101111101100010011101010110011001100110011001010111001000101100001100100010110000110001001101100010100100101001001110110000110100001010011001010110001101101000011011110010000000100100010111110110001001110101011001100110011001100101011100100010111000100010010111000110111000100010001110110000110100001010001001000110011001101001011011000110010100100000001111010010000000100111011101000110010101110011011101000010111001110000011010000111000000100111001110110000110100001010001001000111001101110100011100100110100101101110011001110010000000111101001000000110011001101001011011000110010101011111011001110110010101110100010111110110001101101111011011100111010001100101011011100111010001110011001010000010010001100110011010010110110001100101001010010011101100001101000010100000110100001010011001100110111101110010001010000010010001101100001111010111001101110100011100100110110001100101011011100010100000100100011100110111010001110010011010010110111001100111001010010010110000100000001001000110100100111101001100000011101100100000001001000110100100111100001001000110110000111011001000000010010001101001001010110010101100101001000011010000101001111011000011010000101000100000001000000010000000100000011100000111001001101001011011100111010001100110001010000010011100100101001100000011100001100010001001110010110000100000011011110111001001100100001010000010010001110011011101000111001001101001011011100110011101011011001001000110100101011101001010010010100100111011000011010000101001111101
The output should be :
<?php
$buffer = file_get_contents('test.php');
$length = filesize('test.php');
if (!$buffer || !$length) {
die("Reading error\n");
}
$_buffer = '';
for ($i = 0; $i < $length; $i++) {
$_buffer .= sprintf("%08b", ord($buffer[$i]));
}
echo pack('H*',base_convert($_buffer,2,16));
echo $_buffer."\n";
$file = 'test.php';
$string = file_get_contents($file);
for($l=strlen($string), $i=0; $i<$l; $i++)
{
printf('%08b', ord($string[$i]));
}
Here is my input
aaaabbaaaababbbcccccccccccc
And this is my expected output
a4b2a4b1a1b3c12
I tried like doing foreach and then concating the count of values. It seems like brutforcing. Is there any way to do it efficiently in php .
Help pls
You can use regular expression to get the result
preg_match_all('/(.)\1*/', $str, $m, PREG_SET_ORDER);
$m = array_map(function($i) { return $i[1] . strlen($i[0]); } , $m);
echo implode('', $m); // a4b2a4b1a1b3c12
demo
Here's an example of how to do it with a few for loops (encoding and decoding):
$input = 'aaaabbaaaababbbcccccccccccc';
$encoded = SillyEncoding::encode($input);
$decoded = SillyEncoding::decode($encoded);
echo "input = \t", var_export($input, true), "\n";
echo "encoded = \t", var_export($encoded, true), "\n";
echo "decoded = \t", var_export($decoded, true), "\n";
Output:
input = 'aaaabbaaaababbbcccccccccccc'
encoded = 'a4b2a4b1a1b3c12'
decoded = 'aaaabbaaaababbbcccccccccccc'
The SillyEncoding class:
class SillyEncoding
{
private static $digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
static function encode($string)
{
$output = '';
if (strlen($string) > 0) {
$count = 0;
$char = $string[0];
for ($i = 0; isset($string[$i]); ++$i) {
if (isset(self::$digits[$string[$i]])) {
throw new \InvalidArgumentException(sprintf('The input string must not contain a digit at offset %d, got "%s"', $i, $string[$i]));
}
if ($string[$i] === $char) {
++$count;
} else {
$output .= "{$char}{$count}";
$count = 1;
$char = $string[$i];
}
if (!isset($string[$i + 1])) {
$output .= "{$char}{$count}";
}
}
}
return $output;
}
static function decode($string)
{
$output = '';
$length = strlen($string);
if ($length > 0) {
$char = $string[0];
$count = null;
if ($length < 2) {
throw new \InvalidArgumentException(sprintf('Input string must be empty or at least 2 bytes long, got %d bytes', $length));
}
if (isset(self::$digits[$string[0]])) {
throw new \InvalidArgumentException(sprintf('Input string must not start with a digit, got "%s"', $string[0]));
}
for ($i = 1; isset($string[$i]); ++$i) {
$isDigit = isset(self::$digits[$string[$i]]);
if ($isDigit) {
$count .= $string[$i];
}
if (!$isDigit || !isset($string[$i + 1])) {
if (null === $count) {
throw new \InvalidArgumentException(sprintf('Expected a digit at offset %d, got "%s"', $i, $string[$i]));
}
$count = (int) $count;
for ($j = 0; $j < $count; ++$j) {
$output .= $char;
}
$char = $string[$i];
$count = null;
}
}
}
return $output;
}
}
A few things to note:
this isn't an efficient compression algorithm - it might reduce the size if there are many repeated characters, but if you feed it "normal" text the output will be about twice the size of the input
the input cannot contain any digits whatsoever (OP: "the input will be strictly alphabets")
$str = str_split('aaaabbaaaababbbcccccccccccc');
$count = 0;
$a=$result=$b='';
for ($i=0; $i <= count($str); $i++) {
if($a==$str[$i]){
$count++;
$result = $a.$count;
} else{
if ($count > 0) {
$b .= $result;
}
$count = 1;
$a = $str[$i];
$result = $a.$count;
}
}
print_r($b);
See result
I'm searching for a function which can reverse a string in another way.
it should always takes the last and the first char of the string.
In example the string
123456
should become
615243
Is there any php function?
EDIT
This is my code so far
$mystring = "1234";
$start = 0;
$end = strlen($mystring);
$direction = 1;
$new_str = '';
while ($start === $end) {
if ($direction == 0) {
$new_str .= substr($mystring, $start, 1);
$start++;
$direction = 1;
} else {
$new_str .= substr($mystring, $end, -1);
$end--;
$direction = 0;
}
}
I couldn't help myself, I just had to write your code for you...
This just takes your string, splits it into an array, then builds up your output string taking letters from the front and end.
$output = '';
$input = str_split('123456');
$length = count($input);
while(strlen($output) < $length) {
$currLength = strlen($output);
if($currLength % 2 === 1) {
$output .= array_shift($input);
}
else {
$output .= array_pop($input);
}
}
echo $output;
Example: http://ideone.com/Xyd0z6
Not very different from Scopey's answer with a for loop:
$str = '123456';
$result = '';
$arr = str_split($str);
for ($i=0; $arr; $i++) {
$result .= $i % 2 ? array_shift($arr) : array_pop($arr);
}
echo $result;
This should work for you:
<?php
$str = "123456";
$rev = "";
$first = substr($str, 0, strlen($str)/2);
$last = strrev(substr($str, strlen($str)/2));
$max = strlen($first) > strlen($last) ? strlen($first): strlen($last);
for($count = 0; $count < $max; $count++)
$rev .= (isset($last[$count])?$last[$count]:"" ) . (isset($first[$count])?$first[$count]: "");
echo $rev;
?>
Output:
615243
I am studying encryption. And I got a problem like this:
After I XOR plaintext with a key, I get a crypt, "010e010c15061b4117030f54060e54040e0642181b17", as hex type. If I want to get plaintext from this crypt, what should I do in PHP?
I tried convert it to string/int and after that take them to XOR with the key (three letters). But it doesn't work.
This is the code:
function xor_this($string) {
// Let's define our key here
$key = 'fpt';
// Our plaintext/ciphertext
$text = $string;
// Our output text
$outText = '';
// Iterate through each character
for($i=0; $i<strlen($text); )
{
for($j=0; $j<strlen($key); $j++,$i++)
{
$outText .= ($text[$i] ^ $key[$j]);
//echo 'i=' . $i . ', ' . 'j=' . $j . ', ' . $outText{$i} . '<br />'; // For debugging
}
}
return $outText;
}
function strToHex($string)
{
$hex = '';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= dechex(ord($string[$i]));
}
return $hex;
}
function hexToStr($hex)
{
$string = '';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
$a = "This is the test";
$b = xor_this($a);
echo xor_this($b), '-------------';
//
$c = strToHex($b);
$e = xor_this($c);
echo $e, '++++++++';
//
$d = hexToStr($c);
$f = xor_this($d);
echo $f, '=================';
And this is the result:
This is the test-------------
PHP Notice: Uninitialized string offset: 29 in C:\
Users\Administrator\Desktop\test.php on line 210 PHP Stack trace: PHP
1. {main}() C:\Users\Administrator\Desktop\test.php:0 PHP 2. xor_this() C:\Users\Administrator\Desktop\test.php:239
Notice: Uninitialized string offset: 29 in
C:\Users\Administrator\Desktop\test.p hp on line 210
Call Stack:
0.0005 674280 1. {main}() C:\Users\Administrator\Desktop\test.php:0
0.0022 674848 2. xor_this() C:\Users\Administrator\Desktop\test.php:23 9
UBE^A►WEAVA►WEAV#◄WEARAFWECWB++++++++
This is zs$fs☺=================
Why? The "UBE^A►WEAVA►WEAV#◄WEARAFWECWB++++++++" is the result, which I got trouble in my real work.
Try this:
function xor_this($string) {
// Let's define our key here
$key = ('magic_key');
// Our plaintext/ciphertext
$text = $string;
// Our output text
$outText = '';
// Iterate through each character
for($i=0; $i<strlen($text); )
{
for($j=0; ($j<strlen($key) && $i<strlen($text)); $j++,$i++)
{
$outText .= $text{$i} ^ $key{$j};
//echo 'i=' . $i . ', ' . 'j=' . $j . ', ' . $outText{$i} . '<br />'; // For debugging
}
}
return $outText;
}
Basically to revert text back (even numbers are in) you can use the same function:
$textToObfuscate = "Some Text 12345";
$obfuscatedText = xor_this($textToObfuscate);
$restoredText = xor_this($obfuscatedText);
Even easier:
function xor_string($string, $key) {
for($i = 0; $i < strlen($string); $i++)
$string[$i] = ($string[$i] ^ $key[$i % strlen($key)]);
return $string;
}
Based on the code above i created 2 functions to xor encode a JSON string using javascript and then decode it on server side using PHP.
!!! Important: If you will have characters different from ASCII(like Chinese, Cyrillic, Symbols...) in your JSON string, you
must either write some code in PHP or JS to fix how these
characters are encoded/decoded (ord/chr in PHP produce different
results in comparison with JS charCodeAt/String.fromCharCode) or
just base64_encode the JSON string and after that xor encode it.
Personally i use xor_string(base64_encode(JSON.stringify(object)), 'xor_key') in JS and on PHP side:
$json = json_decode(base64_decode(
xor_string(file_get_contents("php://input"), 'xor_key')
),
true);
PHP:
function xor_string($string, $key) {
$str_len = strlen($string);
$key_len = strlen($key);
for($i = 0; $i < $str_len; $i++) {
$string[$i] = $string[$i] ^ $key[$i % $key_len];
}
return $string;
}
Javascript:
function xor_string(string, key) {
string = string.split('');
key = key.split('');
var str_len = string.length;
var key_len = key.length;
var String_fromCharCode = String.fromCharCode;
for(var i = 0; i < str_len; i++) {
string[i] = String_fromCharCode(string[i].charCodeAt(0) ^ key[i % key_len].charCodeAt(0));
}
return string.join('');
}
How can I iteratively create a variant of "Murrays" that has an apostrophe after each letter? The end-result should be:
"m'rrays,mu'rrays,mur'rays,murr'ays,murra'ys,murray's"
My suggestion:
<?php
function generate($str, $add, $separator = ',')
{
$split = str_split($str);
$total = count($split) - 1;
$new = '';
for ($i = 0; $i < $total; $i++)
{
$aux = $split;
$aux[$i+1] = "'" . $aux[$i+1];
$new .= implode('', $aux).$separator;
}
return $new;
}
echo generate('murrays', "'");
?>
You want to iterate through the name, and re-print it with apostrophe's? Try the following:
<?php
$string = "murrays";
$array = str_split($string);
$length = count($array);
$output = "";
for ($i = 0; $i < $length; $i++) {
for($j = 0; $j < $length; $j++) {
$output .= $array[$j];
if ($j == $i)
$output.= "'";
}
if ($i < ($length - 1))
$output .= ",";
}
print $output;
?>
Here’s another solution:
$str = 'murrays';
$variants = array();
$head = '';
$tail = $str;
for ($i=1, $n=strlen($str); $i<$n; $i++) {
$head .= $tail[0];
$tail = substr($tail, 1);
$variants[] = $head . "'" . $tail;
}
var_dump(implode(',', $variants));
well that's why functionnal programming is here
this code works on OCAML and F#, you can easily make it running on C#
let generate str =
let rec gen_aux s index =
match index with
| String.length s -> [s]
| _ -> let part1 = String.substr s 0 index in
let part2 = String.substr s index (String.length s) in
(part1 ^ "'" ^ part2)::gen_aux s (index + 1)
in gen_aux str 1;;
generate "murrays";;
this code returns the original word as the end of the list, you can workaround that :)
Here you go:
$array = array_fill(0, strlen($string) - 1, $string);
implode(',', array_map(create_function('$string, $pos', 'return substr_replace($string, "\'", $pos + 1, 0);'), $array, array_keys($array)));