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
  • 11,225
  • 12
  • 69
  • 104
  • 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

29

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,787
  • 10
  • 62
  • 110
Andrew
  • 291
  • 3
  • 3
19

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
  • 356,200
  • 43
  • 426
  • 500
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
  • 428,835
  • 81
  • 738
  • 806
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,421,763
  • 867
  • 9,128
  • 9,194
  • 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