I have a field on an object in Salesforce representing the IMEI of a mobile device. I want to validate the input of users to ensure for a correct IMEI number and format. I know the IMEI is using a check digit as last digit.
How do I validate this with a validation rule on a field in Salesforce?
The IMEI is a 15-digit number with 14 relevant digits and a last check digit.
(Note: there is also a 16-digit IMEISV format, which is not considered here)
The check digit is calculated following the Luhn algorithm.
Assuming your Salesforce object (here Asset
) has a custom field IMEI__c
of type Number, the following checks can be applied to validate the IMEI input.
A validation rule checks for the error state. Hence for the length check we need the following validation rule:
LEN(TEXT(IMEI__c)) != 15
If this condition is true, the error state is encountered and we can display an error message to the user and saving the record is blocked.
You can also check the number is larger than 1x10^15, but I prefer this notation to understand directly I am checking for a 15 digit number.
You can also include this easy check in the other check below, but I prefered to do it separately to provide the user with a more specific error message in case of an error.
For this check we need to calculate the check digit by ourselves and validate it against the last digit in the IMEI, representing the check digit.
We extract every single digit by: extract one (1) digit from the middle (MID) at position x from the IMEI converted to text, and convert it back to a number.
VALUE(MID(TEXT(IMEI__c), x, 1))
Starting from the rightmost digit (index=14) (excluding the check digit), we double every second digit.
2*VALUE(MID(TEXT(IMEI__c), 14, 1))
1*VALUE(MID(TEXT(IMEI__c), 13, 1))
2*VALUE(MID(TEXT(IMEI__c), 12, 1))
[...]
2*VALUE(MID(TEXT(IMEI__c), 2, 1))
1*VALUE(MID(TEXT(IMEI__c), 1, 1))
If the number is larger than 9, we need to calculate the cross sum (e.g. 14 => 1 + 4 = 5). Since Salesforce does not provide a cross sum function in validation rules, we use a workaround. The maxmimum number we can encounter is 9x2=18. Hence we check if the number is larger than 9, if yes we substract 10 and add 1 to the sum.
IF(
2*VALUE(MID(TEXT(IMEI__c), 14, 1))>9, # Check number larger than 9
2*VALUE(MID(TEXT(IMEI__c), 14, 1))-10+1, # yes, substract 10 and add 1: 18 => 1+8 = 9 = 18-10+1
2*VALUE(MID(TEXT(IMEI__c), 14, 1)) # no, use raw number
)
To calculate the check digit, we need to find the number to be added to the final sum to reach a multile of 10 (e.g. sum=52 => check digit = 8 => 52 + 8 = 60 = 6 * 10). Hence the check digit is
MOD(
10 - MOD(
<SUMMED VALUES>,
10
),
10
)
Finally we validate this against the check digit from the provided IMEI
VALUE(MID(TEXT(IMEI__c), 15, 1))
The final validation rule then looks like
MOD(
10 - MOD(
IF(2*VALUE(MID(TEXT(IMEI__c), 14, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 14, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 14, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 13, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 13, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 13, 1)))+
IF(2*VALUE(MID(TEXT(IMEI__c), 12, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 12, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 12, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 11, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 11, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 11, 1)))+
IF(2*VALUE(MID(TEXT(IMEI__c), 10, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 10, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 10, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 9, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 9, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 9, 1)))+
IF(2*VALUE(MID(TEXT(IMEI__c), 8, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 8, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 8, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 7, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 7, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 7, 1)))+
IF(2*VALUE(MID(TEXT(IMEI__c), 6, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 6, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 6, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 5, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 5, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 5, 1)))+
IF(2*VALUE(MID(TEXT(IMEI__c), 4, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 4, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 4, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 3, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 3, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 3, 1)))+
IF(2*VALUE(MID(TEXT(IMEI__c), 2, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 2, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 2, 1)))+
IF(1*VALUE(MID(TEXT(IMEI__c), 1, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 1, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 1, 1))),
10
), 10
) != VALUE(MID(TEXT(IMEI__c), 15, 1))
INPUT: 123456789012347
12345678901234 - check digit 7
=> 2*4 + 3 + 2*2 + 1 + 2*0 + 9 + 2*8 + 7 + 2*6 + 5 + 2*4 + 3 + 2*2 + 1
=> 8+3+4+1+0+9+(16)+7+(12)+5+8+3+4+1
=> 8+3+4+1+0+9+(16-10+1)+7+(12-10+1)+5+8+3+4+1
=> 8+3+4+1+0+9+(7)+7+(3)+5+8+3+4+1
=> 63
Missing to next 10 multiple is 7 => IMEI OK!
For an invalid IMEI it looks like