Skip to content

Power Query: SIM ICCID Check

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: