patternjavascriptMinor
Verifying a South African ID
Viewed 0 times
africansouthverifying
Problem
I'm verifying South African IDs with jQuery, the code below works but Id like to know if it could be simplified in anyway or if there is a better way of doing things here?
South African IDs are verified as follows:
And the code:
```
var me = $("#id");
var odd = new Number();
var even_string = new String();
var even_result = new Number();
var even = new Number();
var result = new Number();
// Check length
if( me.val().length == 13 )
{
$.each(me.val(), function(p,v){
if (p%2 == 0 & p != 12)
{
odd += Number(v); // --> 1. Add all odd positions except the last one.
}
else
{
if(p != 12)
{
even_string += String(v); // --> 2.1 Join all even positions.
}
}
});
// 2.2 Multiply even string by two.
even_result = (even_string * 2);
// 3. Add the digits of the new even result in two point two.
$.each(String(even_result), function(p,v){
even += Number(v);
});
// 4. Add answer in three to the answer in one.
result = odd+even;
// 5. Subtract the second digit from step 4. from ten.
result = 10 - Number(String(result).substr(1,1));
// 6. Make sur
South African IDs are verified as follows:
Using ID Number 8001015009087 as an example:
Add all the digits in the odd positions (excluding last digit).
8 + 0 + 0 + 5 + 0 + 0 = 13 .............................[1]
Move the even positions into a field and multiply the number by 2.
011098 x 2 = 22196 .....................................[2]
Add the digits of the result in [2].
2 + 2 + 1 + 9 + 6 = 20 .................................[3]
Add the answer in [3] to the answer in [1].
13 + 20 = 33 ...........................................[4]
Subtract the second digit of [4](i.e. 3) from 10. The number must tally with
the last number in the ID Number. If the result is 2 digits, the last digit is
used to compare against the last number in the ID Number. If the answer differs,
the ID number is invalid.And the code:
```
var me = $("#id");
var odd = new Number();
var even_string = new String();
var even_result = new Number();
var even = new Number();
var result = new Number();
// Check length
if( me.val().length == 13 )
{
$.each(me.val(), function(p,v){
if (p%2 == 0 & p != 12)
{
odd += Number(v); // --> 1. Add all odd positions except the last one.
}
else
{
if(p != 12)
{
even_string += String(v); // --> 2.1 Join all even positions.
}
}
});
// 2.2 Multiply even string by two.
even_result = (even_string * 2);
// 3. Add the digits of the new even result in two point two.
$.each(String(even_result), function(p,v){
even += Number(v);
});
// 4. Add answer in three to the answer in one.
result = odd+even;
// 5. Subtract the second digit from step 4. from ten.
result = 10 - Number(String(result).substr(1,1));
// 6. Make sur
Solution
- jQuery is entirely unnecessary and will just make your solution slower
- Don't initialize to
new Class()- this is not Java. Instead, initialize to the initial value, orundefined(var x;).
- use a function to encapsulate your verification logic, and to separate it from the DOM interface.
- don't call
me.val()more than once; cache the result
- instead of the slow
$.each, use a simpler loop
- You already know the length of the id string, so you can get rid of the
p%2check and simply operate twice on each loop, once on the current position and once on p + 1, and increment by 2 each time (this also results in half as many iterations, speeding up the loop even further).
- Cast using
+string(resulting in a number) and'' + number(resulting in a string)
- split the string into the first 12 and the last 1 at the beginning, so you don't have to keep excluding the last character and re-extracting it.
'string'.slice(-1)is a more concise way to access the last character in a string
- check to make sure that not only is the string 13 characters long, but also that every character is a numeral
With all that and a few stylistic preferences, here's my take on your problem:
function isValidSAID(id) {
var i, c,
even = '',
sum = 0,
check = id.slice(-1);
if (id.length != 13 || id.match(/\D/)) {
return false;
}
id = id.substr(0, id.length - 1);
for (i = 0; c = id.charAt(i); i += 2) {
sum += +c;
even += id.charAt(i + 1);
}
even = '' + even * 2;
for (i = 0; c = even.charAt(i); i++) {
sum += +c;
}
sum = 10 - ('' + sum).charAt(1);
return ('' + sum).slice(-1) == check;
}
if (!isValidSAID(document.getElementById('id').innerHTML)) {
alert('Your South African ID is not valid.');
}Code Snippets
function isValidSAID(id) {
var i, c,
even = '',
sum = 0,
check = id.slice(-1);
if (id.length != 13 || id.match(/\D/)) {
return false;
}
id = id.substr(0, id.length - 1);
for (i = 0; c = id.charAt(i); i += 2) {
sum += +c;
even += id.charAt(i + 1);
}
even = '' + even * 2;
for (i = 0; c = even.charAt(i); i++) {
sum += +c;
}
sum = 10 - ('' + sum).charAt(1);
return ('' + sum).slice(-1) == check;
}
if (!isValidSAID(document.getElementById('id').innerHTML)) {
alert('Your South African ID is not valid.');
}Context
StackExchange Code Review Q#12735, answer score: 4
Revisions (0)
No revisions yet.