Skip to content

Instantly share code, notes, and snippets.

@freak4pc
Last active January 21, 2024 08:29
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save freak4pc/6802be89d019bca57756a675d761c5a8 to your computer and use it in GitHub Desktop.
Save freak4pc/6802be89d019bca57756a675d761c5a8 to your computer and use it in GitHub Desktop.
Israeli ID Validator (Javascript)
function isValidIsraeliID(id) {
var id = String(id).trim();
if (id.length > 9 || id.length < 5 || isNaN(id)) return false;
// Pad string with zeros up to 9 digits
id = id.length < 9 ? ("00000000" + id).slice(-9) : id;
return Array
.from(id, Number)
.reduce((counter, digit, i) => {
const step = digit * ((i % 2) + 1);
return counter + (step > 9 ? step - 9 : step);
}) % 10 === 0;
}
// Usage
["1234567890","001200343", "231740705", "339677395"].map(function(e) {
console.log(e + " is " + (isValidIsraeliID(e) ? "a valid" : "an invalid") + " Israeli ID");
});
// Outputs:
// 1234567890 is an invalid Israeli ID
// 001200343 is an invalid Israeli ID
// 231740705 is a valid Israeli ID
// 339677395 is a valid Israeli ID
extension String {
func isValidIsraeliID() -> Bool {
let trimmed = trimmingCharacters(in: .whitespacesAndNewlines)
let isNumeric = rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
guard 1...9 ~= trimmed.count,
isNumeric else { return false }
let neededZeros = 9 - trimmed.count
let tested = String(repeating: "0", count: neededZeros) + trimmed
return tested.enumerated()
.reduce(into: 0) { counter, args in
let (idx, char) = args
guard let digit = char.wholeNumberValue else { return }
let step = digit * ((idx % 2) + 1)
counter += step > 9 ? step - 9 : step
} % 10 == 0
}
}
@benjamingr
Copy link

Just changing to from mapper argument - we avoid the Number calls:

function isValidIsraeliID(id) {
  var id = String(id).trim();
  if (id.length != 9 || isNaN(id)) return false;

  return Array.from(id, Number).reduce((counter, digit, i) => {
        const step = digit * ((i % 2) + 1);
        return counter + (step > 9 ? step - 9 : step);
    }) % 10 === 0;
}

More dropping the if;

function isValidIsraeliID(id) {
  var id = String(id).trim();
  return (id.length === 9 && !isNaN(id)) && Array.from(id, Number).reduce((counter, digit, i) => {
        const step = digit * ((i % 2) + 1);
        return counter + (step > 9 ? step - 9 : step);
    }) % 10 === 0;
}

Validate it's 9 digits directly:

function isValidIsraeliID(id) {
  return /\d{9}/.test(id) && Array.from(id, Number).reduce((counter, digit, i) => {
        const step = digit * ((i % 2) + 1);
        return counter + (step > 9 ? step - 9 : step);
    }) % 10 === 0;
}

Now that there are no outer variables, we can turn it into a lambda:

Validate it's 9 digits directly:

const isValidIsraeliID = id => /\d{9}/.test(id) && Array.from(id, Number).reduce((counter, digit, i) => {
        const step = digit * ((i % 2) + 1);
        return counter + (step > 9 ? step - 9 : step);
    }) % 10 === 0;

We can map to the step as one step and then reduce as another or do other cool stuff, did the code get better? IDK :D

@davidfeldi
Copy link

davidfeldi commented Jan 18, 2017

Hey Shai,
this script fails for Israeli ID's which are smaller than 9 (which are totally fine -> http://halemo.net/info/idcard/)

you need to verify it in another way like :
if ((id.length > 9) || (id.length < 5)) return false; if (isNaN(id)) return false;

and if the number is too short add trailing zero's
if (IDnum.length < 9) { while(IDnum.length < 9) { IDnum = '0' + IDnum; } }

then you can continue with your ID checker.

👍

@freak4pc
Copy link
Author

freak4pc commented Jan 18, 2017

@davidfeldi Cool edge case! Wasn't aware of the fact IDs under 9 digits are allowed... Never seen a governmental website accepting those but it does seem the algorithm supports this so I'd love to fix it :)

@benjamingr I like the Number mapper idea! Neat!

As for reducing stuff to less lines here, I think it's further taking away from readability, even though it's cool to see how far we can go with it :) Thanks for your thoughts!

@freak4pc
Copy link
Author

Updated based on your comments. Thanks guys ! @davidfeldi @benjamingr .

@theyuv
Copy link

theyuv commented Nov 22, 2017

Hey, do you have code for company id numbers as well?
Or maybe just know what the basic rules are for those?

Thanks.

@adi518
Copy link

adi518 commented Apr 12, 2018

This is an ancient algo that's present many years: https://gist.github.com/adi518/84214b150357291e7523179c331f3bc1

I slightly updated it, but it misses padding. My point though, does it differ logic-wise? If not, I guess you should put yours on npm. There's one entry on npm atm, but it lacks padding and source is not as good. :)

@adi518
Copy link

adi518 commented Apr 15, 2018

Don't need var here: var id = String(id).trim();.

@landesm
Copy link

landesm commented Jan 30, 2021

hello, is there anyway to turn this into a regexp ?
thanks

@freak4pc
Copy link
Author

@landesm Don't see how. Regex is for matching, not complex computation.

@matantech
Copy link

@freak4pc
Thank you for the swift version!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment