13

Is it possible to represent a sequence of hex characters (0-9A-F) with a sequence of 0-9a-zA-Z characters, so the the result sequence is smaller and can be decoded?

For example:

$hex = '5d41402abc4b2a76b9719d911017c592';
echo $string = encode($hex); // someASCIIletters123
echo decode(string) == $hex; //true
Dziamid
  • 10,647
  • 11
  • 66
  • 103
  • I think he means cramming 2 (4-byte) hex digits into one byte (which should be possible all right) – Pekka Sep 20 '11 at 16:32
  • 1
    Looks like you just reinvented base64... Well, base62, but I'd go with the well known and supported everywhere base64 if I were you. – fvu Sep 20 '11 at 16:32
  • 1
    @Robik. I think zie means turn base 16 to base 62. The higher the base, the shorter the string, so the "result sequence" would indeed be "smaller". The 62 digit characters are 0-9a-zA-Z. Neat notion, but I don't know of any simple way to do it. – TRiG Sep 20 '11 at 16:35

5 Answers5

28

I think you're looking for this:

function hex2str($hex) {
    $str = '';
    for($i=0;$i<strlen($hex);$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
    return $str;
}

(From http://www.linux-support.com/cms/php-convert-hex-strings-to-ascii-strings/) (Works like this javascript tool: http://www.dolcevie.com/js/converter.html)

SeinopSys
  • 8,418
  • 9
  • 57
  • 108
Andrew
  • 281
  • 3
  • 3
18

You mean want to convert a string of hex digits into actual hex values?

$hex_string = "A1B2C3D4F5"; // 10 chars/bytes
$packed_string = pack('H*', $hex_string); // 0xA1B2C3D4F5 // 5 chars/bytes.
Marc B
  • 348,685
  • 41
  • 398
  • 480
5

You can trivially adapt the solution I presented here using the function base_convert_arbitrary.

Edit: I had not read carefully enough :) Base 16 to base 62 is still very doable, as above.

See it in action.

Community
  • 1
  • 1
Jon
  • 413,451
  • 75
  • 717
  • 787
3

The built-in php functions may help some landing here on a search:

// https://www.php.net/manual/en/function.hex2bin
$hex = '6578616d706c65206865782064617461';
echo hex2bin($hex); // example hex data
1

Well, something similar, yes... parse the hex characters as a binary value, then convert to base64. That uses a little bit more than 0-9 a-z A-Z, but only a few more characters. Are you okay to use three other characters in addition to those 62? You can use base64_encode to perform the encoding if so.

(You could convert to base32 instead, but that wouldn't be as compact. Converting to bases which aren't powers of 2 is also feasible, but less appealing.)

You'd also need some way of representing a final half-byte if your input sequence had an odd number of characters. You'll probably want to think about that before calling pack to do the original parsing...

Jon Skeet
  • 1,335,956
  • 823
  • 8,931
  • 9,049
  • 2
    @fvu: The 65th character is the equals sign, which may appear only at the end of the encoded string. Google the encoding method to see why you need it. – Jon Sep 20 '11 at 16:45
  • @jon ahhh, you are referring to the pad character that's mandatory in a number of b64 variants. He could as well pick eg RFC4648, Nmtoken or Name and save 1 byte – fvu Sep 20 '11 at 16:48
  • @fvu: Yes, potentially. The benefit of using a "standard" base64 is that it's more easily portable to other platforms. Usually the difference between needing to find 64 characters and needing to find 65 isn't significant. – Jon Skeet Sep 20 '11 at 16:50
  • 1
    @fvu: However, `base64_encode` is built into PHP and lots of other languages, which pretty much dictates what any of us would pick. – Jon Sep 20 '11 at 16:50