RegEx for Isracard (Israel Card) - javascript

I need a Regular expression for Isracard (Israel Credit Card).
Would be very grateful for help, or maybe for some info how to make it.
Format of Isracard 8-9 digits.
ex. Picture of card - http://images.delcampe.com/img_large/auction/000/157/341/572_001.jpg

I found a validation for IsraCard:
<script>
var cardValid=function(cardNo){
var sum = 0, iNum;
for( var i in cardNo+='' ){
iNum = parseInt(cardNo[i]);
sum += i%2?iNum:iNum>4?iNum*2%10+1:iNum*2;
}
return !(sum%10);
};
</script>
Asp vb script IsraCard Credit Card number Validation (8 or 9 digits)
<%
Function IsraCardCheck(strNumber)
comp1 = "987654321"
comp2 = strNumber
srez = 0
if len(comp2) < 9 then comp2 = "0" & comp2
for i = 1 to 9
a = mid(comp1, i, 1)
b = mid(comp2, i, 1)
c = a * b
srez = srez + c
next
if srez mod 11 = 0 then
IsraCheck = true
else
IsraCheck = false
end if
End Function
%>
I just copied the code from there and for more information and details you may want to check the link itself: Anatomy of credit card number formats

Based on what I see here (and without any further guidelines from you on on what an Israel credit card number begins with), this should probably work
(3640|4580)-?([0-9]{4}-?){3}

A simple regex to check if it's a number with 8 or 9 digits:
^[0-9]{8,9}$
Or if a space or dash is allowed between the digits.
^[0-9](?:[ -]?[0-9]){7,8}$
To match for example :
1234-5678-9
1234 5678
1 2 3 4 5 6 7 8 9
1-2-3-4-5-6-7-8
12-34 56-78 9
But a pure regex can't do calculations, like f.e. a modulus check.
So extra code is needed to give a more accurate validation.
Javascript example snippet:
function checkIsracard(creditcardNo){
if(! /^[0-9](?:[ -]?[0-9]){7,8}$/.test(creditcardNo.toString())) return false;
let total = 0;
let cardDigits = creditcardNo.toString().match(/[0-9]/g);
cardDigits.forEach(function(digit, indx){
total += parseInt(digit,10)*(cardDigits.length - indx);
});
return (total%11 === 0);
}
console.log('1234-5678-9:\t'+checkIsracard('1234-5678-9'));
console.log('1234 5679:\t'+checkIsracard('1234 5679'));
console.log('123456789:\t'+checkIsracard(123456789));
console.log('12345679:\t'+checkIsracard(12345679));
console.log('123456781:\t'+checkIsracard('123456781')); // modulus check fail
console.log('12345671:\t'+checkIsracard('12345671')); // modulus check fail
console.log('1234567:\t'+checkIsracard('1234567')); // not enough digits
console.log('1234567890:\t'+checkIsracard('1234567890')); // too many digits
But if the question would be about the 16 digit visa credit card numbers?
For those, the more widely used luhn-algorithm is used.
So that algorithm would be a bit more complicated.

Algorithm explanation: https://web.archive.org/web/20140227235803/http://povolotski.me/2013/09/24/isracard-credit-card-number-validation-2/
function isracardCheck(num) {
if(typeof num !== 'number') num=''+num;
if(num.length < 8 || num.length > 9) return false;
var sum=0;
num.split('').forEach(function(val,key){
sum+=parseInt(val,10)*(num.length-key);
})
return sum % 11 == 0;
}
License: MIT, https://gist.github.com/avimar/e7421f96357bf06acc31d952c7baf84e

Related

Check and convert a phone number

I have a input field for a phonenumber.
Now i want to check with jquery/javascript the syntax and the characters of the number
I only accept this format: 31-123456789 (also more groupes seperated by - will be ok)
Its important to check if there is the international code at first.
I think about to do a kind of replace for replace "()/.:;" characters and check if the first letter is a 0.
But this looks for large code, also there is not check if the user has enter disallowed characters for example Abc...
How i can check and format the following examples in the easiest way?
031(123)123 -> should return 31-123-123
(0123)123 -> should return a error (no international code)
031.123 -> should return a error (no international code)
31.(123)123 -> 31-123-123
+31.123.123 -> 31-123-123
+31 (123) 123 -> 31-123-123
etc.
Thanks for showing and explaing me the way to do it.
Here is a try, that you could build on. It also fill all your requirement.
Now you can simply add your configration to internationalCodes and the method will do its job
// All valid internationl code
var internationalCodes= [
{ codes:["031", "0031", "31"], translateTo: "31", minLength: 8 }
]
var seperatorCount =3;
var seperator = "-";
function getNumber(num){
var notValid = num + " not valid";
num = num.trim().replace(/[^0-9]/g, ""); // replace all none number char
// find the international configration settings
var r = internationalCodes.filter(x=>
x.codes.findIndex(i=> num.substr(0, i.length)== i) != -1)
if (r.length<=0) // no internationalCodes configration
return notValid;
r = r[0];
if (num.length<r.minLength)
return notValid;
var resultNum = r.translateTo;
var code = r.codes.filter(x=> num.substr(0, x.length) == x)[0]
num = num.substr(code.length, num.lengt)
for (var i = 0; i< num.length; i++)
{
if (i % seperatorCount == 0)
resultNum += seperator;
resultNum += num[i];
}
return resultNum;
}
console.log(getNumber("031(123)123"))
console.log(getNumber("(0123)123"))
console.log(getNumber("031.123"))
console.log(getNumber("31.(123)123"))
console.log(getNumber("+31.123.123"))
console.log(getNumber("+31 (123) 123"))
console.log(getNumber("+50 (123) 123"))

How to check if a number that starts with a letter

I have a code below that matches a remainder of an 8 digit number to a letter when divided by 23.
function dniLetter( dni ) {
var lockup = 'TRWAGMYFPDXBNJZSQVHLCKE'
var result = '';
var remainder = dni % 23;
result = lockup.charAt(remainder)
return result; }
How could I improve if the number starts with a negative number (like -2) or start with a letter (A1234567)?
For the negative numbers, you should try replacing dni % 23 by ((dni % 23) + 23) % 23. It will do exactly what you want.
You should use regular expressions.
/^[a-zA-Z-]/.test(yourString) returns true on the specified conditions (and even if it starts with '-A' for instance).

How to check the sum of a divison with javascript?

I want to check For EXAMPLE:
12 - 13 - 14 - 15
12 / 3 = 4 -> OK.
13 / 3 = 4.33 -> NOT OK.
14 / 3 = 4.67 -> NOT OK.
15 / 3 = 5 -> OK.
I want to create a while loop where i use the number i want to divide to 3 as "x".
so:
var x = 0
while (x<20) {
//SOMETHING HERE
x++;
}
Something like that but i dont know the command to check if the sum is a decimal number or not.
Than i want to see the "OK. numbers" in my web browser with a documetn.write( OK numbers )
You can use the modulo operator to check if a number is divisible by another.
Demo
var x = 0;
while (x < 20) {
if (x % 3 === 0) {
document.write(x + ' ');
}
x++;
}
Also, the W3C recommends against using document.write now. Instead it is better to use document.createElement to create an element and insert it that way, like this:
Demo
var span = document.createElement('span');
span.innerHTML = text;
document.body.appendChild(span);

create all possible variations of a string with inserted character

I'm trying to take the variable email and create all possible combinations with a "." in it like so:
Results
andrew
andre.w
andr.ew
andr.e.w
and.rew
and.re.w
and.r.ew
and.r.e.w
an.drew
an.dre.w
an.dr.ew
an.dr.e.w
an.d.rew
an.d.re.w
an.d.r.ew
an.d.r.e.w
a.ndrew
a.ndre.w
a.ndr.ew
a.ndr.e.w
a.nd.rew
a.nd.re.w
a.nd.r.ew
a.nd.r.e.w
a.n.drew
a.n.dre.w
a.n.dr.ew
a.n.dr.e.w
a.n.d.rew
a.n.d.re.w
a.n.d.r.ew
a.n.d.r.e.w
I'm not sure how to do about doing this exactly. I know how to use a loop to go over each character, but as far as the rest goes I'm stumped. I was looking at substr, slice and few other functions but couldn't get anything working.
Code
var email = "andrew";
for (var i = 0; i < email.length; i++) {
console.log( email[i] + "." );
}
That's easy:
var str = 'andrew';
var results = [],
bin;
for (var i = 0; i < Math.pow(2, str.length - 1); ++i) {
bin = i.toString(2).split('').reverse().join('');
results.push(str.replace(/./g, function(letter, index) {
if (bin.charAt(index) == 1) {
letter += '.';
}
return letter;
}));
}
console.log(results);
Demo: http://jsfiddle.net/9qLY6/
Short description:
For 'abc' string there are 2 positions for a dot character: between a and b; b and c. These 2 positions might be presented as a digits of a binary number. All the possible combinations in this case are:
00
01
10
11
If you treat 1 as - . there, and 0 as no . there - you can just iterate over 2^(n-1) numbers and put . if the corresponding bit is set.
If you're interested in a recursive solution like Dinesh mentioned, here's some code to get you started.
function withPeriods(str, prev) {
prev = prev || '';
if(!str || str.length == 0) {
return prev ? [prev] : [];
} else if(str.length == 1) {
return [prev + str];
} else {
var c = str.charAt(0);
var newStr = str.slice(1);
return withPeriods(newStr, prev+c).concat(withPeriods(newStr, prev+c+'.'));
}
}
The idea here is that you are working your way through the string, keeping the current result in the 'prev' variable. If the string is length 0 or 1, there's nothing left to do. Otherwise, you need consider two options: one where you take a character from 'str' and add it to 'prev', and one where you do that but also add a '.'
If you think about it, you need to either insert a dot, or not insert one, at every possible location in the string (between any two characters). A funky way to do this is to realize that if you have n characters, there are n-1 places. If you wrote the combinations of period = 1 and no period = 0, then you can write all possible solutions as a 2^n-1 binary sequence. Showing this for a four letter word "word":
000 word
001 wor.d
010 wo.rd
011 wo.r.d
100 w.ord
101 w.or.d
110 w.o.rd
111 w.o.r.d
In pseudo code (can't test JS syntax right now):
n = strlen( email );
combinations = 1 << n - 1; // left shift operation
for i = 0 to combinations - 1:
dot = 1
for j = 0 to n:
print email[j];
if dot & i:
print '.'
dot << 1;
Can you take it from here?
You might take a recursive approach to this problem. Maybe you can use the base case as a string with 2 characters.

How to create a function that converts a Number to a Bijective Hexavigesimal?

Maybe i am just not that good enough in math, but I am having a problem in converting a number into pure alphabetical Bijective Hexavigesimal just like how Microsoft Excel/OpenOffice Calc do it.
Here is a version of my code but did not give me the output i needed:
var toHexvg = function(a){
var x='';
var let="_abcdefghijklmnopqrstuvwxyz";
var len=let.length;
var b=a;
var cnt=0;
var y = Array();
do{
a=(a-(a%len))/len;
cnt++;
}while(a!=0)
a=b;
var vnt=0;
do{
b+=Math.pow((len),vnt)*Math.floor(a/Math.pow((len),vnt+1));
vnt++;
}while(vnt!=cnt)
var c=b;
do{
y.unshift( c%len );
c=(c-(c%len))/len;
}while(c!=0)
for(var i in y)x+=let[y[i]];
return x;
}
The best output of my efforts can get is: a b c d ... y z ba bb bc - though not the actual code above. The intended output is suppose to be a b c ... y z aa ab ac ... zz aaa aab aac ... zzzzz aaaaaa aaaaab, you get the picture.
Basically, my problem is more on doing the ''math'' rather than the function. Ultimately my question is: How to do the Math in Hexavigesimal conversion, till a [supposed] infinity, just like Microsoft Excel.
And if possible, a source code, thank you in advance.
Okay, here's my attempt, assuming you want the sequence to be start with "a" (representing 0) and going:
a, b, c, ..., y, z, aa, ab, ac, ..., zy, zz, aaa, aab, ...
This works and hopefully makes some sense. The funky line is there because it mathematically makes more sense for 0 to be represented by the empty string and then "a" would be 1, etc.
alpha = "abcdefghijklmnopqrstuvwxyz";
function hex(a) {
// First figure out how many digits there are.
a += 1; // This line is funky
c = 0;
var x = 1;
while (a >= x) {
c++;
a -= x;
x *= 26;
}
// Now you can do normal base conversion.
var s = "";
for (var i = 0; i < c; i++) {
s = alpha.charAt(a % 26) + s;
a = Math.floor(a/26);
}
return s;
}
However, if you're planning to simply print them out in order, there are far more efficient methods. For example, using recursion and/or prefixes and stuff.
Although #user826788 has already posted a working code (which is even a third quicker), I'll post my own work, that I did before finding the posts here (as i didnt know the word "hexavigesimal"). However it also includes the function for the other way round. Note that I use a = 1 as I use it to convert the starting list element from
aa) first
ab) second
to
<ol type="a" start="27">
<li>first</li>
<li>second</li>
</ol>
:
function linum2int(input) {
input = input.replace(/[^A-Za-z]/, '');
output = 0;
for (i = 0; i < input.length; i++) {
output = output * 26 + parseInt(input.substr(i, 1), 26 + 10) - 9;
}
console.log('linum', output);
return output;
}
function int2linum(input) {
var zeros = 0;
var next = input;
var generation = 0;
while (next >= 27) {
next = (next - 1) / 26 - (next - 1) % 26 / 26;
zeros += next * Math.pow(27, generation);
generation++;
}
output = (input + zeros).toString(27).replace(/./g, function ($0) {
return '_abcdefghijklmnopqrstuvwxyz'.charAt(parseInt($0, 27));
});
return output;
}
linum2int("aa"); // 27
int2linum(27); // "aa"
You could accomplish this with recursion, like this:
const toBijective = n => (n > 26 ? toBijective(Math.floor((n - 1) / 26)) : "") + ((n % 26 || 26) + 9).toString(36);
// Parsing is not recursive
const parseBijective = str => str.split("").reverse().reduce((acc, x, i) => acc + ((parseInt(x, 36) - 9) * (26 ** i)), 0);
toBijective(1) // "a"
toBijective(27) // "aa"
toBijective(703) // "aaa"
toBijective(18279) // "aaaa"
toBijective(127341046141) // "overflow"
parseBijective("Overflow") // 127341046141
I don't understand how to work it out from a formula, but I fooled around with it for a while and came up with the following algorithm to literally count up to the requested column number:
var getAlpha = (function() {
var alphas = [null, "a"],
highest = [1];
return function(decNum) {
if (alphas[decNum])
return alphas[decNum];
var d,
next,
carry,
i = alphas.length;
for(; i <= decNum; i++) {
next = "";
carry = true;
for(d = 0; d < highest.length; d++){
if (carry) {
if (highest[d] === 26) {
highest[d] = 1;
} else {
highest[d]++;
carry = false;
}
}
next = String.fromCharCode(
highest[d] + 96)
+ next;
}
if (carry) {
highest.push(1);
next = "a" + next;
}
alphas[i] = next;
}
return alphas[decNum];
};
})();
alert(getAlpha(27)); // "aa"
alert(getAlpha(100000)); // "eqxd"
Demo: http://jsfiddle.net/6SE2f/1/
The highest array holds the current highest number with an array element per "digit" (element 0 is the least significant "digit").
When I started the above it seemed a good idea to cache each value once calculated, to save time if the same value was requested again, but in practice (with Chrome) it only took about 3 seconds to calculate the 1,000,000th value (bdwgn) and about 20 seconds to calculate the 10,000,000th value (uvxxk). With the caching removed it took about 14 seconds to the 10,000,000th value.
Just finished writing this code earlier tonight, and I found this question while on a quest to figure out what to name the damn thing. Here it is (in case anybody feels like using it):
/**
* Convert an integer to bijective hexavigesimal notation (alphabetic base-26).
*
* #param {Number} int - A positive integer above zero
* #return {String} The number's value expressed in uppercased bijective base-26
*/
function bijectiveBase26(int){
const sequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const length = sequence.length;
if(int <= 0) return int;
if(int <= length) return sequence[int - 1];
let index = (int % length) || length;
let result = [sequence[index - 1]];
while((int = Math.floor((int - 1) / length)) > 0){
index = (int % length) || length;
result.push(sequence[index - 1]);
}
return result.reverse().join("")
}
I had to solve this same problem today for work. My solution is written in Elixir and uses recursion, but I explain the thinking in plain English.
Here are some example transformations:
0 -> "A", 1 -> "B", 2 -> "C", 3 -> "D", ..
25 -> "Z", 26 -> "AA", 27 -> "AB", ...
At first glance it might seem like a normal 26-base counting system
but unfortunately it is not so simple.
The "problem" becomes clear when you realize:
A = 0
AA = 26
This is at odds with a normal counting system, where "0" does not behave
as "1" when it is in a decimal place other than then unit.
To understand the algorithm, consider a simpler but equivalent base-2 system:
A = 0
B = 1
AA = 2
AB = 3
BA = 4
BB = 5
AAA = 6
In a normal binary counting system we can determine the "value" of decimal places by
taking increasing powers of 2 (1, 2, 4, 8, 16) and the value of a binary number is
calculated by multiplying each digit by that digit place's value.
e.g. 10101 = 1 * (2 ^ 4) + 0 * (2 ^ 3) + 1 * (2 ^ 2) + 0 * (2 ^ 1) + 1 * (2 ^ 0) = 21
In our more complicated AB system, we can see by inspection that the decimal place values are:
1, 2, 6, 14, 30, 62
The pattern reveals itself to be (previous_unit_place_value + 1) * 2.
As such, to get the next lower unit place value, we divide by 2 and subtract 1.
This can be extended to a base-26 system. Simply divide by 26 and subtract 1.
Now a formula for transforming a normal base-10 number to special base-26 is apparent.
Say the input is x.
Create an accumulator list l.
If x is less than 26, set l = [x | l] and go to step 5. Otherwise, continue.
Divide x by 2. The floored result is d and the remainder is r.
Push the remainder as head on an accumulator list. i.e. l = [r | l]
Go to step 2 with with (d - 1) as input, e.g. x = d - 1
Convert """ all elements of l to their corresponding chars. 0 -> A, etc.
So, finally, here is my answer, written in Elixir:
defmodule BijectiveHexavigesimal do
def to_az_string(number, base \\ 26) do
number
|> to_list(base)
|> Enum.map(&to_char/1)
|> to_string()
end
def to_09_integer(string, base \\ 26) do
string
|> String.to_charlist()
|> Enum.reverse()
|> Enum.reduce({0, nil}, fn
char, {_total, nil} ->
{to_integer(char), 1}
char, {total, previous_place_value} ->
char_value = to_integer(char + 1)
place_value = previous_place_value * base
new_total = total + char_value * place_value
{new_total, place_value}
end)
|> elem(0)
end
def to_list(number, base, acc \\ []) do
if number < base do
[number | acc]
else
to_list(div(number, base) - 1, base, [rem(number, base) | acc])
end
end
defp to_char(x), do: x + 65
end
You use it simply as BijectiveHexavigesimal.to_az_string(420). It also accepts on optional "base" arg.
I know the OP asked about Javascript but I wanted to provide an Elixir solution for posterity.
I have published these functions in npm package here:
https://www.npmjs.com/package/#gkucmierz/utils
Converting bijective numeration to number both ways (also BigInt version is included).
https://github.com/gkucmierz/utils/blob/main/src/bijective-numeration.mjs

Categories