简体   繁体   中英

How can I cram 6+31 numeric characters into 22 alphanumeric characters?

I've got a 6-digit number and a 31-digit number (eg "234536" & "201103231043330478311223582826") that I need to cram into the same 22-character alphanumeric field in an API using PHP. I tried converting each to base 32 (had to use a custom function as base_convert() doesn't handle big numbers well) and joining with a single-character delimiter, but that only gets me down to 26 characters. It's a REST API, so the characters need to be URI-safe.

I'd really like to do this without creating a database table cross referencing the two numbers with another reference value, if possible. Any suggestions?

Use a radix of 62 instead. That will get you 3.35 characters for the former and 17.3 characters for the latter, for an upper total of 22 characters.

>>> math.log(10**6)/math.log(62)
3.3474826039165504
>>> math.log(10**31)/math.log(62)
17.295326786902177

You can write something like pack() that works with big numbers using bc. Here is my quick solution, it converts your second number in a 13-character string. Pretty nice !

<?php
$i2 = "201103231043330478311223582826";

function pack_large($i) {
    $ret = '';
    while(bccomp($i, 0) !== 0) {
        $mod = bcmod($i, 256);
        $i = bcsub($i, $mod);
        $ret .= chr($mod);
        $i = bcdiv($i, 256);
    }

    return $ret;
}

function unpack_large($s) {
    $ret = '0';

    $len = strlen($s);
    for($i = $len - 1; $i >= 0; --$i) {
        $add = ord($s[$i]);
        $ret = bcmul($ret, 256);
        $ret = bcadd($ret, $add);
    }

    return $ret;
}

var_dump($i2);
var_dump($pack = pack_large($i2));
var_dump(unpack_large($pack));

Sample output :

string(30) "201103231043330478311223582826"
string(13) "jàÙl¹9±̉"
string(47) "201103231043330478311223582826.0000000000000000"

Since you need URL-friendly characters, use base64_encode on the packed string, this will give you a 20-character string (18 if your remove the padding).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM