联通物联网卡ICCID校验位的计算方法探究

本文探讨了联通物联网卡ICCID的校验位计算方法,通过实验发现了一个修正算法,使得19位ICCID加上校验位能匹配联通平台的20位ICCID,最终得出优雅的计算公式。
摘要由CSDN通过智能技术生成

SIM卡的ICCID校验位的计算方法,应该不是什么隐私或者机密吧,最近关于这个有点小发现,故写出来与大家分享一下。

ICCID简介

ICCID (Integerate Circuit Card Identity),集成电路卡识别码,是SIM卡的唯一识别号码。ICCID长为19~20位,其中最后一位是校验位(当然也有另外,中移动的某些卡就不是校验位,而是普通的序列号)。关于其它位的含义,可自行百度。

背景

最近要处理中国联通物联网卡的相关业务,需要对接联通的Jasper平台,封装成自己的一套API给客户用,查询卡的信息是通过卡的ICCID(移动、电信用的是MSISDN)。同事给过来一张联通的卡号清单,有ICCID和MSISDN,通过API查询其中一个ICCID的相关信息,结果没查到,于是通过浏览器在联通的管理平台再次查询,还是没查到,这就纳闷了!询问同事,同事说要在ICCID后面加上*,才能查询到。测试了一下,果然可以查到,只是查出的号码多了一位!

原来,同事给我的号码清单,其中ICCID只有19位,而通过API或者管理平台,需要20位的ICCID才能查询,其中第二十位就是前面19位的校验位。

现在问题来了:如何计算ICCID的校验位?

第一部分:问题初探

首先是百度,通过“iccid 校验位”关键字查询,很多人问与我同样的问题,大部分介绍的都是Luhn算法,其中知乎上有位热心的网友给出了详细的关于ICCID的介绍,以及Luhn算法的维基百科链接。进入该维基百科的页面,都是些英文,后面是各种语言的Luhn算法实现,由于目前是用PHP开发,就把PHP版本的代码复制了下来:

function checkLuhn($number) {
   
    $sum = 0;
    $numDigits = strlen($number)-1;
    $parity = $numDigits % 2;
    for ($i = $numDigits; $i >= 0; $i--) {
        $digit = substr($number, $i, 1);
        if (!$parity == ($i % 2)) {
  $digit <<= 1;}
        $digit = ($digit > 9) ? ($digit - 9) : $digit;
        $sum += $digit;
    }
    return (0 == ($sum % 10));
}

由于是求校验位,显然,return那行代码不对,我们只需要求校验和除10的余数就行了。如下:

function checkLuhn($number) {
   
    $sum = 0;
    $numDigits = strlen($number)-1;
    $parity = $numDigits % 2;
    for ($i = $numDigits; $i >= 0; $i--) {
        $digit = substr($number, $i, 1);
        if (!$parity == ($i % 2)) {
  $digit <<= 1;}
        $digit = ($digit > 9) ? ($digit - 9) : $digit;
        $sum += $digit;
    }
    return (
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值