aboutsummaryrefslogtreecommitdiffstats
path: root/pySim-prog.py
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-12-07 12:34:13 +0100
committerSylvain Munaut <tnt@246tNt.com>2011-12-08 19:39:49 +0100
commit2c0ff3a1677a232f2617b5aba1a1002f16e7c7d3 (patch)
tree269319e149bd2cff51dc3c736a27b11a0112a0de /pySim-prog.py
parent5dffefbf0c49340033c0854b592a2741da0935a0 (diff)
correctly compute the ICCID (19 digits, including luhn checksum)
Diffstat (limited to 'pySim-prog.py')
-rwxr-xr-xpySim-prog.py15
1 files changed, 11 insertions, 4 deletions
diff --git a/pySim-prog.py b/pySim-prog.py
index d057a51..493d434 100755
--- a/pySim-prog.py
+++ b/pySim-prog.py
@@ -188,6 +188,10 @@ def _dbi_binary_quote(s):
return ''.join(out)
+def calculate_luhn(cc):
+ num = map(int, str(cc))
+ check_digit = 10 - sum(num[-2::-2] + [sum(divmod(d * 2, 10)) for d in num[::-2]]) % 10
+ return 0 if check_digit == 10 else check_digit
def gen_parameters(opts):
"""Generates Name, ICCID, MCC, MNC, IMSI, SMSP, Ki from the
@@ -206,11 +210,11 @@ def gen_parameters(opts):
# Digitize MCC/MNC (5 or 6 digits)
plmn_digits = _mcc_mnc_digits(mcc, mnc)
- # ICCID (20 digits)
+ # ICCID (19 digits, E.118), though some phase1 vendors use 20 :(
if opts.iccid is not None:
iccid = opts.iccid
- if not _isnum(iccid, 20):
- raise ValueError('ICCID must be 20 digits !');
+ if not _isnum(iccid, 19):
+ raise ValueError('ICCID must be 19 digits !');
else:
if opts.num is None:
@@ -222,7 +226,7 @@ def gen_parameters(opts):
plmn_digits # MCC/MNC on 5/6 digits
)
- ml = 20 - len(iccid)
+ ml = 18 - len(iccid)
if opts.secret is None:
# The raw number
@@ -231,6 +235,9 @@ def gen_parameters(opts):
# Randomized digits
iccid += _digits(opts.secret, 'ccid', ml, opts.num)
+ # Add checksum digit
+ iccid += ('%1d' % calculate_luhn(iccid))
+
# IMSI (15 digits usually)
if opts.imsi is not None:
imsi = opts.imsi