PHP: Convert Hexadecimal String to a-z and A-Z and 0-1

Using PHP, how can I convert this:
3eb24feacab0c1f1054a5133b5000b28

into a shorter string that uses numbers and lower case and uppercase letters?
LVL 10
skijAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
Uhh, what would the expected output be?  Does each pair of characters (eg: 3e, b2, etc) represent something you want in the output?  What would you want to get from "00" here?
0
F PCommented:
Use this function:

function hextostr($hex)
{
    $str='';

    for ($i = 0; $i < strlen($hex) - 1; $i += 2)
    {
        $str .= chr(hexdec($hex[$i].$hex[$i+1]));
    }

    return $str;
}

This hex string = "48654c4c6f20576f526c4421"
... would return = "HeLLo WoRlD!"

Resources and citations from here:

http://www.stringfunction.com/hex-string.html  <- online conversion test tool
http://www.stringfunction.com/php/hexdec-hex-string.html   <- tutorial
0
F PCommented:
( your hex string ....  

 "3eb24feacab0c1f1054a5133b5000b28" = ">²OêÊ°ÁñJQ3µ ("

)
0
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

ChloesDadCommented:
As Ray said, the problem with that is hex of 00 is null so you wont be able to differentiate between

3eb24feacab0c1f1054a5133b5000b28

and

3eb24feacab0c1f1054a5133b500000000000b28

as they will both give

">²OêÊ°ÁñJQ3µ (" when printed

The same will be true of any non-printable character which those from &h00 to &h1F
0
skijAuthor Commented:
The output should only contain letters a-z and A-Z and the numbers 0-9.  No spaces or other characters such as > or ê or Á should be included in the output.
0
Slick812Commented:
hello skij, , Do u need a "filtering" method for HEX input, as if you have a HEX string like -
          "3eb24feacab0c1f1054a5133b5000b28"
you require an output to be -
         "OJQ3"
? ? ?
0
F PCommented:
There's a filter added:

function hextostr($hex)
{
    $str='';
    $chars = 'abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789';

    for($i = 0; $i < strlen($hex) - 1; $i += 2)
    {
        $alpha = chr(hexdec($hex[$i].$hex[$i+1]));

        if(strpos($chars, $alpha) !== FALSE)
        {
            $str .=  $alpha;
        }
    }

    return $str;
}

Open in new window

0
Slick812Commented:
mine is more mathematical -

function getAlpha($str) {
$ary = str_split($str,2);
$str = '';
for ($i=0; $i < count($ary); ++$i) {
   $dec = hexdec($ary[$i]);
   if ((($dec > 47) && ($dec < 58)) || 
      (($dec > 64) && ($dec < 91)) || 
      (($dec > 96) && ($dec < 123))) 
      $str .= chr($dec);
   }
return $str;
}



$hex = '3eb24feacab0c1f1054a5133b5000b28';
$hex = getAlpha($hex);
echo 'HEX Filter is= ',$hex;

Open in new window

0
F PCommented:
change:

for ($i=0; $i < count($ary); ++$i)

Open in new window


to

foreach($ary as $hexval)

Open in new window


Then:

if ((($dec > 47) && ($dec < 58)) || 
      (($dec > 64) && ($dec < 91)) || 
      (($dec > 96) && ($dec < 123))) 

Open in new window


To:

switch(TRUE)
    case [...]

Open in new window


http://php.net/manual/en/control-structures.switch.php

... and it is competitive, but still slower. I like the flow otherwise.
0
Ray PaseurCommented:
I was going to try to write a hex-to-character example for this question, but as I re-read the answers I think Frank Pennock has mostly answered your question.  And at the same time I think there may be a subtext or back-story to the question that we do not have in evidence here.  The real question may be "why do you want to do this?" Maybe you can tell us a little more about the nature of the application?  We do not need technical details - just the "50,000 foot" view.  Where does this data come from?  What do you want to do with it and why?  Where are you going to view or store the results of this conversion?  If you can tell us the essential things about the application we may be able to suggest good ways to approach the problem.
0
Slick812Commented:
comment to Frank Pennock, Thanks for the suggestions, I implemented your code changes as -
function getAlpha2($str) {
$ary = str_split($str,2);
$str = '';
foreach($ary as $hexval) {
  $dec = hexdec($hexval);
  switch (true) {
    case (($dec > 47) && ($dec < 58)):
    case (($dec > 64) && ($dec < 91)):
    case (($dec > 96) && ($dec < 123)): $str .= chr($dec);
  }
}
return $str;
}

Open in new window

and it seems to work as well as my first version on some different HEX strings.
I much prefer to use the direct code handling in for() loops, other than the representative symbolic in  foreach() loops, as the foreach() needs to go to the trouble of making a Copy of the value in the array, although you can get around this with the & -
      foreach($ary as &$hexval)
but I can have more control in for() loops and go in the reverse direction or start at a place other than the first.

The switch() was not something I thought about here, and I like your thinking on that point.
I like to cooperate coding in building web apps, but it is a rare thing here at EE, at least that's my view.
Frank, you seem like a knowledgeable coder in PHP and JS, Glad you are now among the code heads here on EE. welcome to the stumble bumble, of EE!
0
F PCommented:
 foreach($ary as &$hexval)

Open in new window



... regardless of the reference, you still need to unset $hexval after the loop.

I basically use a switch() case every time I'm using more than 1 OR statement, or more than 2 elseif. It's just cleaner.

- Thanks for your compliments! I'm glad to be here. It's just rare to find people who collaborate without being offput or offended. I like how you take the time to learn what happens behind the scenes of the code and not just willy nilly use poor methods which slow things down.
0
Slick812Commented:
Frank, I do see many many code blocks shown here in questions, that are from sources years, maybe even a decade old, that use poor judgement in picking the operations for work, that the PHP coders have inherited over the years, as copy and paste examples, mostly due to the very short operational and how to use , explanations in the PHP official manual, , but if I read all of the user comments below the manual explanations, I see that there can be much more to use and have better code work. With the very fast transition now, from click browser, to touch app Mobil, many PHP web developers seem to be two and three steps behind in the knowledge required for responsive interactive touch phone web sites, resulting in  (as you put it) "willy nilly poor methods which slow things down".
0
skijAuthor Commented:
Thank you all for your ideas.  I am looking for something that can be converted back and forth.  No data should be destroyed in the conversion.  The closest thing I can think of would be to base64_encode() however that would include characters other than letters and numbers.
0
Ray PaseurCommented:
Are you wanting to produce the hexadecimal representations of a string of characters, then reproduce the characters from the hex string?  Maybe something like what they do here?
https://www.branah.com/ascii-converter

PHP base64_encode() and base64_decode() are certainly reversible.  They can be paired with some kind of filter function to remove the non-alphanumeric characters.  But I'm still looking for the "why" in this question.  If we understand that, we can probably show you a best-practices solution instead of just guessing about data conversions.  Maybe if you can show us some of the expected "real world" input it would help us give you a good answer.
0
F PCommented:
You're talking about using RSA encryption then. I didn't know you wanted to actually create object level encryption. RSA is the best alphanumeric encryption you'll find, and the phpseclib library in PHP can work directly with it. Have a look here:

http://phpseclib.sourceforge.net/
0
Ray PaseurCommented:
@Frank:  That makes sense, but wouldn't RSA encryption handle non-alpha-numeric characters?  That's the part that has me stumped - what is the input?  Why not just filter the input if you don't want non-alpha characters?

Here's my baseline example for encryption and binary-safe transport.  But I have to say, I didn't see encryption as a potential solution in the way the question was phrased!
http://iconoun.com/demo/encrypt_decrypt.php
<?php // demo/encrypt_decrypt.php

/**
 * Show how to encrypt and decrypt information
 * with binary-safe transport over the internet
 *
 * http://php.net/manual/en/ref.mcrypt.php
 * http://php.net/manual/en/mcrypt.ciphers.php
 *
 * Note parallel construction in the mcrypt_XXcrypt() functions
 */
error_reporting(E_ALL);


class Encryption
{
    protected $key;

    public function __construct($key='quay')
    {
        // THE KEY MUST BE KNOWN TO BOTH PARTS OF THE ALGORITHM
        $this->key = $key;
    }

    public function encrypt($text)
    {
        // ENCRYPT THE DATA
        $data = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->key, $text, MCRYPT_MODE_ECB);

        // MAKE IT base64() STRING SAFE FOR STORAGE AND TRANSMISSION
        return base64_encode($data);
    }

    public function decrypt($text)
    {
        // DECODE THE DATA INTO THE BINARY ENCRYPTED STRING
        $text = base64_decode($text);

        // DECRYPT THE STRING
        $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->key, $text, MCRYPT_MODE_ECB);

        // DECLOP NUL-BYTES BEFORE THE RETURN
        return trim($data);
    }
}


// INSTANTIATE AN ENCRYPTION OBJECT FROM THE CLASS
$c = new Encryption();

// INITIALIZE VARS FOR LATER USE IN THE HTML FORM
$encoded = $decoded = NULL;

// IF ANYTHING WAS POSTED SHOW THE DATA
if (!empty($_POST["clearstring"]))
{
    $encoded = $c->encrypt($_POST["clearstring"]);
    echo "<br/>{$_POST["clearstring"]} YIELDS ENCODED ";
    var_dump($encoded);
}

if (!empty($_POST["cryptstring"]))
{
    $decoded = $c->decrypt($_POST["cryptstring"]);
    echo "<br/>{$_POST["cryptstring"]} YIELDS DECODED ";
    var_dump($decoded);
}

// CREATE THE FORM USING HEREDOC NOTATION
$form = <<<FORM
<form method="post">
<input name="clearstring" value="$decoded" />
<input type="submit" value="ENCRYPT" />
<br/>
<input name="cryptstring" value="$encoded" />
<input type="submit" value="DECRYPT" />
</form>
FORM;

echo $form;

Open in new window

0
Slick812Commented:
@ skij, , You say -
"I am looking for something that can be converted back and forth.  No data should be destroyed in the conversion"

But you can not just leave out the characters you filter away, and then ever get them back in a reverse "String to HEX" conversion.
You did not answer, my question , which to me is important -

Do u need a "filtering" method for HEX input, as if you have a HEX string like -
          "3eb24feacab0c1f1054a5133b5000b28"
you require an output to be -
         "OJQ3" , ? ?

I am really unsure about the drift this question has taken, into encryption , How did this HEX conversion relate to encryption? ?

 I really do NOT understand your reference to the base64_encode(), as there are 3 characters that it can output that are not in your output set as-
 /   +  =

If you do not need a Filtering character elimination, then you best stick with the HEX, as it uses only letters and numbers, , However I have done Base32 for Binary to ascii characters, and I can use any set of characters for the output I type into the substitution set -
function base32_enc($Plain){
$chr32 = 'W7CpYv1amXc0t2gdMefSji4R5kbLzxGy';
$len=strlen($Plain);
$chop=$len&1;
for($i=0;$i<$chop;++$i)$Plain.=chr(0);
$out1='';
for($i=0;$i<strlen($Plain);$i+=2){
   $wd=ord($Plain{$i})+(ord($Plain{$i+1})<<8);
   for($v=0;$v<3;++$v){
           $mod1=$wd%32;
		$out1 .=$chr32{$mod1};
		$wd=($wd-$mod1)/32;
           }
    }
if($chop)$out1[strlen($out1)-1]='I';
return $out1;
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
F PCommented:
Yeah, I'm confused as to what exactly needs to be done, because the original question said take hex and convert it to a string. That's what was done and now it doesn't seem to answer the question.
0
F PCommented:
If you're just looking to compress the hex, I would say leave it as is within a string format and then use gzcompress() to make the string smaller.

http://php.net/manual/en/function.gzcompress.php

Last I checked, hexadecimal is already alphanumeric.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.