Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@benjamingr benjamingr commented Dec 21, 2016

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

This comment has been minimized.

Copy link

@davidfeldi 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

This comment has been minimized.

Copy link
Owner Author

@freak4pc 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

This comment has been minimized.

Copy link
Owner Author

@freak4pc freak4pc commented Jan 18, 2017

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

@theyuv

This comment has been minimized.

Copy link

@theyuv 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

This comment has been minimized.

Copy link

@adi518 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

This comment has been minimized.

Copy link

@adi518 adi518 commented Apr 15, 2018

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

@landesm

This comment has been minimized.

Copy link

@landesm landesm commented Jan 30, 2021

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

@freak4pc

This comment has been minimized.

Copy link
Owner Author

@freak4pc freak4pc commented Jan 30, 2021

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

@matantech

This comment has been minimized.

Copy link

@matantech matantech commented Feb 17, 2021

@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