一个数值压缩思路

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

 

 提供个思路,仅供参考:
(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;
}

来源:网络

此条目发表在technologys分类目录。将固定链接加入收藏夹。