Just like one can check an IMEI number for validity, one can also check a SIM ICC ID in much the same (but a slightly different) way.
Where IMEI numbers are fixed at 15 characters, a SIM ICC ID can have between 18 and 21 characters (19 to 22 including a check digit). This makes it a bit harder to perform the check, because you can’t start at the front and work your way towards the end – because the Luhn MOD 10 check is based on the sequence starting AT the end.
Ugh.
Anyhoo:
Note that the number 8931 is based on SIM cards provided in The Netherlands. Adjust accordingly!
let
ICCIDCheck = (input as text) as text =>
if (try Number.FromText(Text.Trim(input)) otherwise -1) = -1
then input
else
if Text.Length(Text.Trim(input)) < 19
or Text.Length(Text.Trim(input)) > 22
or Text.StartsWith(Text.Trim(input), "8931") = false
then "Invalid"
else if Number.Mod(
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 1, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 3, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 5, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 7, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 9, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 11, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 13, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 15, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 17, 1)) +
Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 19, 1)) +
(if Text.Length(Text.Trim(input)) >=21
then Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 21, 1))
else 0) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 2, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 2, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 2, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 4, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 4, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 4, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 6, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 6, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 6, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 8, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 8, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 8, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 10, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 10, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 10, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 12, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 12, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 12, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 14, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 14, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 14, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 16, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 16, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 16, 1)) * 2 - 9)) +
(if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 18, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 18, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 18, 1)) * 2 - 9)) +
(if Text.Length(Text.Trim(input)) >= 20
then (if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 20, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 20, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 20, 1)) * 2 - 9))
else 0
) +
(if Text.Length(Text.Trim(input)) >= 22
then (if Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 22, 1)) * 2 < 10
then (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 22, 1)) * 2)
else (Number.FromText(Text.Middle(Text.Trim(input), Text.Length(Text.Trim(input)) - 22, 1)) * 2 - 9))
else 0
)
, 10) = 0
then "OK"
else "Failed checksum"
in
ICCIDCheck
Code language: JavaScript (javascript)
Some information on how an ICC ID is built up: