49 |
49 |
def lpad(s, l, c='f'):
|
50 |
50 |
return c * (l - len(s)) + s
|
51 |
51 |
|
|
52 |
def half_round_up(n):
|
|
53 |
return (n + 1)//2
|
|
54 |
|
|
55 |
# IMSI encoded format:
|
|
56 |
# For IMSI 0123456789ABCDE:
|
|
57 |
#
|
|
58 |
# | byte 1 | 2 upper | 2 lower | 3 upper | 3 lower | ... | 9 upper | 9 lower |
|
|
59 |
# | length in bytes | 0 | odd/even | 2 | 1 | ... | E | D |
|
|
60 |
#
|
|
61 |
# If the IMSI is less than 15 characters, it should be padded with 'f' from the end.
|
|
62 |
#
|
|
63 |
# The length is the total number of bytes used to encoded the IMSI. This includes the odd/even
|
|
64 |
# parity bit. E.g. an IMSI of length 14 is 8 bytes long, not 7, as it uses bytes 2 to 9 to
|
|
65 |
# encode itself.
|
|
66 |
#
|
|
67 |
# Because of this, an odd length IMSI fits exactly into len(imsi) + 1 // 2 bytes, whereas an
|
|
68 |
# even length IMSI only uses half of the last byte.
|
|
69 |
|
52 |
70 |
def enc_imsi(imsi):
|
53 |
71 |
"""Converts a string imsi into the value of the EF"""
|
54 |
|
l = (len(imsi) + 1) // 2 # Required bytes
|
|
72 |
l = half_round_up(len(imsi) + 1) # Required bytes - include space for odd/even indicator
|
55 |
73 |
oe = len(imsi) & 1 # Odd (1) / Even (0)
|
56 |
|
ei = '%02x' % l + swap_nibbles(lpad('%01x%s' % ((oe<<3)|1, imsi), 16))
|
|
74 |
ei = '%02x' % l + swap_nibbles('%01x%s' % ((oe<<3)|1, rpad(imsi, 15)))
|
57 |
75 |
return ei
|
58 |
76 |
|
59 |
77 |
def dec_imsi(ef):
|
... | ... | |
61 |
79 |
if len(ef) < 4:
|
62 |
80 |
return None
|
63 |
81 |
l = int(ef[0:2], 16) * 2 # Length of the IMSI string
|
64 |
|
swapped = swap_nibbles(ef[2:])
|
|
82 |
l = l - 1 # Encoded length byte includes oe nibble
|
|
83 |
swapped = swap_nibbles(ef[2:]).rstrip('f')
|
65 |
84 |
oe = (int(swapped[0])>>3) & 1 # Odd (1) / Even (0)
|
66 |
|
if oe:
|
|
85 |
if not oe:
|
|
86 |
# if even, only half of last byte was used
|
67 |
87 |
l = l-1
|
68 |
|
if l+1 > len(swapped):
|
|
88 |
if l != len(swapped) - 1:
|
69 |
89 |
return None
|
70 |
|
imsi = swapped[1:l+2]
|
|
90 |
imsi = swapped[1:]
|
71 |
91 |
return imsi
|
72 |
92 |
|
73 |
93 |
def dec_iccid(ef):
|