Byte array in PHP - php

I have a a php string:
e.g. df299cc4cda279e4d7344b42a8006d94488c753f
This is representing a 20 bit HEX output. How would I select the n'th byte? For example if I select the 3rd one it should return 9c.
Thanks.

You can take a look at chunk_split() or str_split() and get a result like:
$string = "df299cc4cda279e4d7344b42a8006d94488c753f";
$bytes = str_split($string, 2);
$yourByte = $bytes[2];

$bytes = str_split($string, 2);
echo $bytes[2];
Or you may want to convert the string to actual binary using hex2bin, then echo the index [2] of the string, possibly converting back to hex for output.

Given $n = byte number (3 in your example) and $data = string with hex output,
return substr($data, ($n - 1) * 2, 2)

Related

how to convert binary into base64? [duplicate]

I know this is a pretty silly question, but I don't know what to do.
I have an arbitrary binary number, say,
1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111
I want to convert it to Base 64 using PHP - and every way I try gives me a different result. Even different online converters convert it differently:
http://home2.paulschou.net/tools/xlate/
http://convertxy.com/index.php/numberbases/
PHP's base_convert only works up to base36, and base64_encode expects a string.
What do I do?
UPDATE: I implemented the solution functions suggested by #binaryLV, and it did work well.
However, I compared the results to PHP's built-in base_convert. It turned out that base_convert to base36 returns shorter values that the custom base64 function! (And yes, I did prepend a '1' to all the binary numbers to ensure leading zeros aren't lost).
I have noticed, too, that base_convert is quite innacurate with large numbers. So I need is a function which works like base_convert, but accurately and, preferably, up to base 64.
Length of a string in example is 160. It makes me think that it holds info about 160/8 characters. So,
split string into parts, each part holds 8 binary digits and describes single character
convert each part into a decimal integer
build a string from characters, that are made from ASCII codes from 2nd step
This will work with strings with size n*8. For other strings (e.g., 12 binary digits) it will give unexpected results.
Code:
function bin2base64($bin) {
$arr = str_split($bin, 8);
$str = '';
foreach ( $arr as $binNumber ) {
$str .= chr(bindec($binNumber));
}
return base64_encode($str);
}
$bin = '1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111';
echo bin2base64($bin);
Result:
kDICQIMBEFjDBxwMBJiAASBYwgc=
Here's also function for decoding it back to string of binary digits:
function base64bin($str) {
$result = '';
$str = base64_decode($str);
$len = strlen($str);
for ( $n = 0; $n < $len; $n++ ) {
$result .= str_pad(decbin(ord($str[$n])), 8, '0', STR_PAD_LEFT);
}
return $result;
}
var_dump(base64bin(bin2base64($bin)) === $bin);
Result:
boolean true
PHP has a built in base 64 encoding function, see documentation here. If you want the decimal value of the binary string first use bin2dec, there are similar functions for hexadecimals by the way. The documentation is your friend here.
[EDIT]
I might have misunderstood your question, if you want to convert between actual bases (base 2 and 64) use base_convert
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
echo base64_encode ($number);
This is if you want the exact string be converted into Base 64.
To convert a binary number (2 base) to a 64 base use the base_convert function.
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
base_convert ($number , 2, 64);

Binary String to Array to HEX Color

Trying to import some color pallets from a program which stores them in binary format. I need them to be split and converted to hex. I didn't think it would be too difficult after seeing this tool: https://www.binaryhexconverter.com/binary-to-hex-converter, but I am not getting the results I expected.
$color = "[00001010,11101111,11000001,00000000,11111111,11111111,11111111,11111111,11111111,11111111,01100000,00000000,10010000,00000000,11111111,11111111,01100000,00000000,10010000,00000000,11111111,11111111,01100000,00000000,10010000,00000000,11111111,11111111,01100000,00000000,11111111,11111111,11111111,11111111,01100000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,10001010,00000000,11000000,00000000,11111111,11111111,10001010,00000000,11000000,00000000,11111111,11111111,10001010,00000000,11000000,00000000,11111111,11111111,11000000,00000000,11111111,11111111,11111111,11111111,10010000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,01110011,01110101,01110010,01100111,01100101,01110010,01111001,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,10101110,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,10101110,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11000000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11000000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,11000000,11000000,11000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000]";
$new_arr = array_map('trim', explode(',', trim($color, '[]')));
$arr = array_chunk($new_arr, 3);
foreach($arr as $bingroup){
print("<div style='position:absolute;height:20px;width:20px;background:#");
foreach($bingroup as $binitem){
$hex = bin2hex ($binitem);
print($hex);
}
print("'></div>");
}
So I import the string, trim, explode it to an array, group them into groups of 3 and then run over it with a couple foreach loops using bin2hex() -> simple right? Why then am I getting
<div style="position:absolute;height:20px;width:20px;background:#303030303130313031313130313131313131303030303031"></div>
See, this is happening as you want
<?php
$color = "[00001010,11101111,11000001,00000000,11111111,11111111,11111111,11111111,11111111,11111111,01100000,00000000,10010000,00000000,11111111,11111111,01100000,00000000,10010000,00000000,11111111,11111111,01100000,00000000,10010000,00000000,11111111,11111111,01100000,00000000,11111111,11111111,11111111,11111111,01100000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,10001010,00000000,11000000,00000000,11111111,11111111,10001010,00000000,11000000,00000000,11111111,11111111,10001010,00000000,11000000,00000000,11111111,11111111,11000000,00000000,11111111,11111111,11111111,11111111,10010000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,01110011,01110101,01110010,01100111,01100101,01110010,01111001,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,10101110,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,10101110,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11000000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11000000,00000000,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,11000000,11000000,11000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000]";
$new_arr = array_map('trim', explode(',', trim($color, '[]')));
$arr = array_chunk($new_arr, 3);
foreach($arr as $bingroup){
print("<div style='position:absolute;height:20px;width:20px;background:#");
foreach($bingroup as $binitem){
$hex = base_convert($binitem, 2, 16);
if(strlen($hex) == 1){
$hex = '0'.$hex;
}
print($hex);
}
print("'></div>");
}
This happens because you're not actually converting a binary number to hexadecimal, which bin2hex() expects. You're trying to convert a string representation of a binary number to hexadecimal.
The ASCII character "0" is "30" in hexadecimal, character "1" is "31" in hexadecimal. So converting the string "00001010" to hexadecimal using binhex() will return the string "3030303031303130".
A workaround to get what you want is to first convert the string to decimal (funnily enough, bindec() does support strings) and then go from decimal to hexadecimal:
echo dechex(bindec("00001010"));
// "a"
// -> 00001010 in binary = 10 in decimal = "a" in hexadecimal
So you need to change this line:
// $hex = bin2hex ($binitem);
$hex = dechex(bindec($binitem));
CSS either supports single character color codes ("#abc") for all colors or double for all ("#aabbcc"), but not a mixture of the two so you might also need to add an extra check to make sure color codes < 16 will be output as "0a" instead of just "a".
You can use sprintf() for this. This formats the decimal (after conversion) as hexadecimal padded with a 0 to 2 characters.
$hex = sprintf('%02x', bindec($binitem));

Converting large numbers into letters (and back again)

Is there a term for the idea of storing large numbers as letters? For example let's say I have the (relatively small) number 138201162401719 and I want to shrink the number of characters (I know this does not help with saving disk space) to the fewest possible number of characters. There are 26 letters in the English alphabet (but i count them as 25 since we need a zero letter). If I start splitting up my large number into pieces that are each 25 or less I get:
13, 8, 20, 11, 6, 24, 0, 17, 19
If I then count the numbers of the alphabet a=0, b=1, c=2, d=3... I can convert this to:
NIULGYART
So I went from 15 digits long (138201162401719) to 9 characters long (NIULGYART). This could of course be easily converted back to the original number as well.
So...my first question is "Does this have a name" and my second "Does anyone have PHP code that will do the conversion (in both directions)?"
I am looking for proper terminology so that I can do my own research in Google...though working code examples are cool too.
This only possible if you're considering to store your number before processing as a string. Because you can't store huge number as integers. You will lost the precision (13820116240171986468445 will be stored as 1.3820116240172E+22) so the alot of digits are lost.
If you're considering storing the number as a string this will be your answer:
Functions used: intval, chr and preg_match_all.
<?php
$regex = '/(2[0-5])|(1[0-9])|([0-9])/';
$numberString = '138201162401719';
preg_match_all($regex, $numberString, $numberArray, PREG_SET_ORDER);
echo($numberString . " -> ");
foreach($numberArray as $value){
$character = chr (intval($value[0]) + 65);
echo($character);
}
?>
Demo
This is the result:
138201162401719 -> NIULGYART
Here's how I would do it:
Store the big number as a string and split it into an array of numbers containing one digit each
Loop through the array extract 2-digit chunks using substr()
Check if the number is less than 26 (in which case, it is an alphabet) and add them to an array
Use array_map() with chr() to create a new array of characters from the above array
Implode the resulting array to get the cipher
In code:
$str = '138201162401719';
$arr = str_split($str);
$i = 0; // starting from the left
while ($i < count($arr)) {
$n = substr($str, $i, 2);
$firstchar = substr($n, 0, 1);
if ($n < 26 && $firstchar != 0) {
$result[] = substr($str, $i, 2);
$i += 2; // advance two characters
} else {
$result[] = substr($str, $i, 1);
$i++; // advance one character
}
}
$output = array_map(function($n) {
return chr($n+65);
}, $result);
echo implode($output); // => NIULGYART
Demo.
As an alternative, you could convert the input integer to express it in base 26, instead of base 10. Something like (pseudocode):
func convertBase26(num)
if (num < 0)
return "-" & convertBase26(-num) // '&' is concatenate.
else if (num = 0)
return "A"
endif
output = "";
while (num > 0)
output <- ('A' + num MOD 26) & output // Modulus operator.
num <- num DIV 26 // Integer division.
endwhile
return output
endfunc
This uses A = 0, B = 1, up to Z = 25 and standard place notation: 26 = BA. Obviously a base conversion is easily reversible.
strtr() is a magnificent tool for this task! It replaces the longest match as is traverses the string.
Code: (Demo)
function toAlpha ($num) {
return strtr($num, range("A", "Z"));
}
$string = toAlpha("138201162401719");
echo "$string\n";
$string = toAlpha("123456789012345");
echo "$string\n";
$string = toAlpha("101112131415161");
echo "$string\n";
$string = toAlpha("2625242322212019");
echo "$string";
Output:
NIULGYART
MDEFGHIJAMDEF
KLMNOPQB
CGZYXWVUT
Just flip the lookup array to reverse the conversion: https://3v4l.org/YsFZu
Merged: https://3v4l.org/u3NQ5
Of course, I must mention that there is a vulnerability with converting a sequence of letters to numbers and back to letters. Consider BB becomes 11 then is mistaken for eleven which would traslate to L when converted again.
There are ways to mitigate this by adjusting the lookup array, but that may not be necessary/favorable depending on program requirements.
And here is another consideration from CodeReview.
I have been trying to do the same thing in PHP without success.
Assuming I'm using the 26 letters of the English alphabet, starting with A = 0 down to Z as 25:
I find the highest power of 26 lower than the number I am encoding. I divide it by the best power of 26 I found. Of the result I take away the integer, convert it to a letter and multiply the decimals by 26. I keep doing that until I get a whole number. It's ok to get a zero as it's an A, but if it has decimals it must be multiplied.
For 1 billion which is DGEHTYM and it's done in 6 loops obviously. Although my answer demonstrates how to encode, I'm afraid it does not help doing so on PHP which is what I'm trying to do myself. I hope the algorithm helps people out there though.

PHP: bin2hex and working with impossible numbers

Haven't slept in awhile, so I'm probably missing something simple. Basically, I am taking a number and converting it to three characters. Max number of possibilities is 256*256*256 (16777216). I convert it with:
public function s_encode($num) {
$num = chr($num / 65536).chr($num / 256).chr($num % 256);
return bin2hex($num);
}
And convert it back with:
public function s_decode($hex) {
$a = pack("H*", $hex);
$b = ord(substr($a, 1, 1));
$c = ord(substr($a, 2, 1));
$d = ord(substr($a, 0, 1));
return (($d * 65536) + ($b * 256)) + $c;
}
What's strange, is this actually works. It does what I want it to, but how could it? In the first code, where I convert it to three characters, the second part of the conversion is:
chr($num / 256)
If the number is greater than 65536, this should cause an error, but it doesn't. If I were to use unpack instead of bin2hex, it will cause an error. bin2hex won't. Why and how is bin2hex so magical?
chr() only looks at the lowest 8 bits of its input:
echo "'".chr(320)."'";
yields...
'#'
as does...
echo "'".chr(64)."'";
http://ideone.com/65Itz
According to the comments in the php docs, chr will take the parameter modulo 256. Even negative integers work. bin2hex doesn't do that operation, and fails on invalid inputs.

Convert a binary number to Base 64

I know this is a pretty silly question, but I don't know what to do.
I have an arbitrary binary number, say,
1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111
I want to convert it to Base 64 using PHP - and every way I try gives me a different result. Even different online converters convert it differently:
http://home2.paulschou.net/tools/xlate/
http://convertxy.com/index.php/numberbases/
PHP's base_convert only works up to base36, and base64_encode expects a string.
What do I do?
UPDATE: I implemented the solution functions suggested by #binaryLV, and it did work well.
However, I compared the results to PHP's built-in base_convert. It turned out that base_convert to base36 returns shorter values that the custom base64 function! (And yes, I did prepend a '1' to all the binary numbers to ensure leading zeros aren't lost).
I have noticed, too, that base_convert is quite innacurate with large numbers. So I need is a function which works like base_convert, but accurately and, preferably, up to base 64.
Length of a string in example is 160. It makes me think that it holds info about 160/8 characters. So,
split string into parts, each part holds 8 binary digits and describes single character
convert each part into a decimal integer
build a string from characters, that are made from ASCII codes from 2nd step
This will work with strings with size n*8. For other strings (e.g., 12 binary digits) it will give unexpected results.
Code:
function bin2base64($bin) {
$arr = str_split($bin, 8);
$str = '';
foreach ( $arr as $binNumber ) {
$str .= chr(bindec($binNumber));
}
return base64_encode($str);
}
$bin = '1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111';
echo bin2base64($bin);
Result:
kDICQIMBEFjDBxwMBJiAASBYwgc=
Here's also function for decoding it back to string of binary digits:
function base64bin($str) {
$result = '';
$str = base64_decode($str);
$len = strlen($str);
for ( $n = 0; $n < $len; $n++ ) {
$result .= str_pad(decbin(ord($str[$n])), 8, '0', STR_PAD_LEFT);
}
return $result;
}
var_dump(base64bin(bin2base64($bin)) === $bin);
Result:
boolean true
PHP has a built in base 64 encoding function, see documentation here. If you want the decimal value of the binary string first use bin2dec, there are similar functions for hexadecimals by the way. The documentation is your friend here.
[EDIT]
I might have misunderstood your question, if you want to convert between actual bases (base 2 and 64) use base_convert
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
echo base64_encode ($number);
This is if you want the exact string be converted into Base 64.
To convert a binary number (2 base) to a 64 base use the base_convert function.
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
base_convert ($number , 2, 64);

Categories