跪求数字压缩算法,该怎么解决

跪求数字压缩算法
背景:
身份证号码的前17位,是数字类型的字符串:比如"53010119870615158",现在书写的时候占了17个字符,有没有办法将其压缩短一些,比如,10位之类的。

需求: 
1. 可以采用十六进制,或者10进制,或者 数字和字母的组合
2. 不易区分的数字字母除外,比如: I 和 1, O 和 0 .
3. 需要生成的新字符,可以转换为原来的值(即无损).
4. 需要有稳定的生成的位数,可以在最开始补0之类的。
请各位大神提供解决方案,或者思路,或者链接都可以。

------解决方案--------------------
530101198706015158
我提供一个思路吧.身份证号至少可以分成这三节.
第一节表示一个地址.
第二节表示出生日期.
第三节表示顺序号和男女性别.

我只从出生日期上来考虑.
假设你的系统能运行到2100年.

那么你的系统里人的出生年份将是[1900, 2100]这个区间.
200年而已.

将十进制的200先转为二进制. 再将二进制转为十六进制.

我们知道, 2的8次方是256, 怎么样够了吧.
也就是说, 用16进制的00~FF就可以表示1900~2100年的所有年份了. 还有剩余!

这样, 本来四位年份就变成了两位了对不对~

我们再继续. 月份, 一年只有12个月. 用一个十六进制就搞定了.又省了一位对不对~

日期, 最多31. 如果16进制也要两位.

好了. 然后你再去想办法搞到地址对应的身份证前6位.
肯定可以减少的.

PS. 以上我是在16进制的范畴下讨论的.
如果你胆子更大一点, 完全可以用更大的进制! 0~9 A~Z a~z可用的进制大的很呢~ 16进制只是其中很小的一份.

再PS. 以上讨论是基于新身份证号的. 现在还有老身份证号. 需要一个额外的位置, 表示这是新的身份证还是老的身份证
------解决方案--------------------
提供个思路,仅供参考:
(1)17位身份证号末位(最右边一位)可能是X,可以保留不进行处理
(2)由于36*36 = 1296 > 1000,所以我们可以用一个36进制的两位数(最大是1295)完全表示一个10进制的3位数(最大是999),这样,我们可以把17位身份证的前15位压缩成10位(每三位压缩成两位),再直接拼接上身份证号的后2位,就成了一个12位的固定长度的身份证号(当然也可以再以某种方式处理后两位,使之变成一位)
(3)设计一个36进制,例如0~9a~z,这样的话,就可以写出如下的转换:

string compressId(const string& id)
{
    int num, i, k = 0, tmp;
    string compressed(12, ' ');//预留12个字符的空间
    for(i = 0; i < 15; i += 3){
        num = (id[i]-'0')*100 + (id[i+1]-'0')*10 + (id[i+2]-'0');
        tmp = num/36; 
        num %= 36;
        compressed[k++] = tmp > 9 ? tmp-10+'a' : tmp+'0';//36进制数的高位
        compressed[k++] = num > 9 ? num-10+'a' : num+'0';//36进制数的低位
    }
    compressed[10] = id[15];
    compressed[11] = id[16];
    return compressed;
}
string retrieveId(const string& compressed)
{
    int num, i, k = 0;
    string id(17, ' ');//预留17个字符的空间
    for(i = 0; i < 10; i += 2){
        num = (compressed[i] > '9' ? compressed[i]-'a'+10 : compressed[i]-'0') * 36 +
              (compressed[i+1] > '9' ? compressed[i+1]-'a'+10 : compressed[i+1]-'0');
        id[k++] = num/100 + '0';//10进制数的百位
        num %= 100;
        id[k++] = num/10 + '0';//10进制数的十位
        num %= 10;
        id[k++] = num + '0';//10进制数的个位
    }
    id[15] = compressed[10];
    id[16] = compressed[11];
    return id;
}