Reverse Bits JavaScript - javascript

The problem is standard but the solution in JavaScript takes a lot more effort to code.
I got the solution but my answer is coming half of what is desired.
Problem Description
Reverse the bits of a 32-bit unsigned integer A.
Problem Constraints
0 <= A <= 2^32
Input Format
The first and only argument of input contains an integer A.
Output Format
Return a single unsigned integer denoting minimum xor value.
Example Input
Input 1:
0
Input 2:
3
Example Output
Output 1:
0
Output 2:
3221225472
My solution
function modulo(a, b) {
return a - Math.floor(a/b)*b;
}
function ToUint32(x) {
return modulo(parseInt(x), Math.pow(2, 32));
}
function revereBits(A){
A = A.toString(2);
while (A.length < 31){
A = "0"+A;
}
var reverse = 0;
var NO_OF_BITS = A.length;
for(var i = NO_OF_BITS; i >= 1; i--){
var temp = (parseInt(A, 2) & (1 << i - 1));
if(temp){
reverse |= 1 << (NO_OF_BITS - i);
}
}
if( reverse << 1 < 0 ) reverse = ToUint32(reverse << 1);
return reverse;
}
Now, in the line
if( reverse << 1 < 0 ) reverse = ToUint32(reverse << 1);
You see that I have to double the answer. I cannot, however, get the part of why is this required.
I took the approach from https://www.geeksforgeeks.org/write-an-efficient-c-program-to-reverse-bits-of-a-number/
Had to make few adjustments to it. For example, run the loop from 31 to 1 rather than 0 to 31. The latter gives negative values in first left shift operation for i = 0 itself.
Can someone please help in fixing this solution and point to the problem in this?
UPDATE - Problem is related to Bit manipulation. So guys, please don't answer or comment for anything consisting of in-built string functions of Javascript. Cheers!

You should be able to do it using just bitwise operators, and a typed array to solve the sign issue:
Update
Changing slightly approach of the rev function after #bryc comment. Since having multiple function for "history" purpose makes the answer difficult to read, I'm putting first the latest code.
However, I'm keeping the comments about the different steps – the rest can be found in the edit history.
function rev(x) {
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8);
x = (x >>> 16) | (x << 16);
return x >>> 0;
}
This is the same code you would write in other languages as well to reverse bits, the only difference here is the addition of the typed array.
As #harold pointed out in the comment, the zero-fill right shift returns an unsigned (it's the only bitwise operator to do so) therefore we can omit the typed array and just add >>> 0 before the return.
In fact, doing >>> 0 is commonly used to simulate the ToUint32 in JS polyfilll; e.g.:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
// 2. Let lenValue be the result of calling the Get internal method
// of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;

function reverseBits(integer, bitLength) {
if (bitLength > 32) {
throw Error(
"Bit manipulation is limited to <= 32 bit numbers in JavaScript."
);
}
let result = 0;
for (let i = 0; i < bitLength; i++) {
result |= ((integer >> i) & 1) << (bitLength - 1 - i);
}
return result >>> 0; // >>> 0 makes it unsigned even if bit 32 (the sign bit) was set
}

Try this:
function reverseBits(num) {
let reversed = num.toString(2);
const padding = "0";
reversed = padding.repeat(32 - reversed.length) + reversed;
return parseInt(reversed.split('').reverse().join(''), 2);
}
console.log(reverseBits(0)); // 0
console.log(reverseBits(3)); // 3221225472

Related

What does >>>= mean? [duplicate]

This question already has answers here:
JavaScript triple greater than
(4 answers)
Closed 2 years ago.
While I was checking the lodash code, I came up with a question I was curious about.
// slice.js
function slice(array, start, end) {
let length = array == null ? 0 : array.length
if (!length) {
return []
}
start = start == null ? 0 : start
end = end === undefined ? length : end
if (start < 0) {
start = -start > length ? 0 : (length + start)
}
end = end > length ? length : end
if (end < 0) {
end += length
}
length = start > end ? 0 : ((end - start) >>> 0)
start >>>= 0
let index = -1
const result = new Array(length)
while (++index < length) {
result[index] = array[index + start]
}
return result
}
export default slice
Specifically, I am curious about why this code exists in this part.
((end - start) >>> 0)
As far as I know, the bit operator shifts the position of a binary number, but I am curious why it shifts 0 times.
>>>=
And >>>= This operator is the first time I saw it.
Does anyone know what it means?
>>> is called unsigned right shift (or zero fill right shift). You may have known of left/right shift.
Basically it shifts the specified number of bits to the right. You can find it here
So >>>= is basically the right shift assignment.
a >>>= b
is equivalent to:
a = a >>> b
The unsigned right shift operator (a >>> b) does shift the bits of the variable a by b bits as you said.
It always returns a positive integer, so a >>> 0 would be used to make sure that the input isn't say, negative, or a string, or otherwise not a positive integer.
a >>>= b is similar to a += b, that is, it applies the right shift b to a and then assigns the output to a, similar to how a += b adds b to a and then assigns the result to a. So a >>>= b is equivalent to a = a >>> b like a += b is equivalent to a = a + b.

Javascript get single bit

I have an integer and i want to check if a single bit is 0 or 1.
What is the best practise for doing that?
An example of what i'm doing at this moment:
const myInt = 8; // Binary in 32 Bit integer = 00000000000000000000000000001000
const myBit = myInt << 28 >>> 31; // 00000000000000000000000000000001
if (myBit === 1) {
//do something
}
But i think that this isn't the best methode for doing this.
Have you any better idea?
EDIT:
It is always the same bit i want to check, but the integer is different
myInt = 8+4; // 1100
n = 3;
(myInt >> n) & 0x1; // 1
n = 2;
(myInt >> n) & 0x1; // 1
n = 1;
(myInt >> n) & 0x1; // 0
n = 0;
(myInt >> n) & 0x1; // 0
general solution shifts your number by N bits to right, and applies bitmask, that leaves only last bit, all other are set to 0
I think you can use the bitwise AND
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
my32Bit = 123414123;
twoBy7 = 128;
//check the 7th bit
if (my32Bit & twoBy7) {
// should return 1 if the 7thbit is 1
}
You could take the bit and a left shift << with bitwise AND & operator.
var value = 10,
bit;
for (bit = 0; bit < 4; bit++) {
console.log(bit, !!(value & (1 << bit)));
}

16-bit binary arithmetic in Javascript

Javascript has only one number type: a 64-bit floating point.
Using Javascript, I need to implement a hashing algorithm which is designed to be written in C with 16 bit unsigned integers.
The main operation is something like this (pseudocode):
uint16 n = 0;
string s = "abcd1234";
for (int i = 0; i < s.length; i += 1) {
n ^= (n << 2) + (n >> 3) + s[i];
}
return n;
Of course, this produces one result when using uint16 values and a different result if n is a 64-bit floating point.
My best solution to the problem so far is to convert the results of each bitwise operation to <= 16 bits, using a function like this (javascript):
function uint16 (n) {
return parseInt(n.toString(2).slice(-16), 2);
}
and performing the operation something like this (javascript):
for (var i = 0; i < s.length; i +=1 ) {
n ^= uint16(uint16(n << 2) + uint16(n >>> 3) + s.charCodeAt(i));
}
but I'm not 100% confident this will always produce the correct results.
Is there any standard way to emulate 16-bit unsigned bitwise operations on a number value in Javascript?
You can use bitwise AND.
It operates on 32 bit integers, but you can just "and" with 0xffff.
function uint16 (n) {
return n & 0xFFFF;
}
Additionally, bit shift operations (<<, >>>) also operate on 32 bit integers, so you only really need to call the uint16 function before assignment:
for (var i = 0; i < s.length; i +=1 ) {
n ^= uint16((n << 2) + (n >>> 3) + s.charCodeAt(i));
}
I suspect #Amit's version will execute faster but this is a workaround I have had success with:
//create a typed container, we'll work only in the first index.
const idx = 0;
const n = new Uint16Array(1);
for (int i = 0; i < s.length; i += 1) {
n[idx] ^= (n[idx] << 2) + (n[idx] >> 3) + s[i];
}

Signed to Unsigned and Vice Versa (arithmetical)

How to convert a number from unsigned to signed?
signed: -32768 to 32767
unsigned: 0 to 65535
I am solving the problem in JavaScript. The situation is that I have a number that goes e.g. from 0 to 65535 and I want to convert it to a reasonable signed value.
e.g.: 65535 should become -1.
Please do not use any bit related operations but something arithmetical.
I guess this should be language independent assuming that we use a data type that is big enough.
Update:
Implementation according to the answer further down:
function convertWordToShort(ival) {
if (isNaN(ival) === false) {
if (ival > 32767) {
ival = ival - 65536;
}
}
return ival;
}
function convertShortToWord(ival) {
if (isNaN(ival) === false) {
if (ival < 0) {
ival = ival + 65536;
}
}
return ival;
}
function convertIntToDWord(ival) {
if (isNaN(ival) === false) {
if (ival < 0) {
ival = ival + 4294967296;
}
}
return ival;
}
function convertDWordToInt(ival) {
if (isNaN(ival) === false) {
if (ival > 2147483647) {
ival = ival - 4294967296;
}
}
return ival;
}
Just test if the number is over halfway, then subtract the modulus.
if(x > 32767) {x = x - 65536;}
In the case that you would be looking for bitwise operation related answers, you could try the following:
to convert something akin to a 16 bit unsigned integer (i.e 0 <= n <= 65535) to a 16 bit signed one:
(number << 16) >> 16
Or:
new Int16Array([number])[0]
Where number in both cases is your 16 bit number.
As a side note the reason the first solution works is because if you bit shift to the right 16 times, the most significant bit of your 16 bit number will actually become the most significant bit of the 32 bit JavaScript integer (so if the most significant bit was a 1, it'd make the number negative), and so when you shift it to the left 16 times it'd shift while keeping the standard 2s complement form and retain the value/sign it gained from being shifted to the right previously, see this Wikipedia article for more:
https://en.m.wikipedia.org/wiki/Arithmetic_shift
function signed(bits, value) { return value & (1 << (bits - 1)) ? value - (1 << bits) : value; }
signed(8, 0xFF); // returns -1
signed(16, 0xFF); // returns 255

Implementation of Luhn algorithm

I am trying to implement simple validation of credit card numbers. I read about the Luhn algorithm on Wikipedia:
Counting from the check digit, which is the rightmost, and moving
left, double the value of every second digit.
Sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5)
together with the undoubled digits from the original number.
If the total modulo 10 is equal to 0 (if the total ends in zero)
then the number is valid according to the Luhn formula; else it is
not valid.
On Wikipedia, the description of the Luhn algorithm is very easily understood. However, I have also seen other implementations of the Luhn algorithm on Rosetta Code and elsewhere (archived).
Those implementations work very well, but I am confused about why they can use an array to do the work. The array they use seems to have no relation with Luhn algorithm, and I can't see how they achieve the steps described on Wikipedia.
Why are they using arrays? What is the significance of them, and how are they used to implement the algorithm as described by Wikipedia?
Unfortunately none of the codes above worked for me. But I found on GitHub a working solution
// takes the form field value and returns true on valid number
function valid_credit_card(value) {
// accept only digits, dashes or spaces
if (/[^0-9-\s]+/.test(value)) return false;
// The Luhn Algorithm. It's so pretty.
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
the array [0,1,2,3,4,-4,-3,-2,-1,0] is used as a look up array for finding the difference between a number in 0-9 and the digit sum of 2 times its value. For example, for number 8, the difference between 8 and (2*8) = 16 -> 1+6 = 7 is 7-8 = -1.
Here is graphical presentation, where {n} stand for sum of digit of n
[{0*2}-0, {1*2}-1, {2*2}-2, {3*2}-3, {4*2}-4, {5*2}-5, {6*2}-6, {7*2}-7....]
| | | | | | | |
[ 0 , 1 , 2 , 3 , 4 , -4 , -3 , -2 ....]
The algorithm you listed just sum over all the digit and for each even spot digit, look up the the difference using the array, and apply it to the total sum.
Compact Luhn validator:
var luhn_validate = function(imei){
return !/^\d+$/.test(imei) || (imei.split('').reduce(function(sum, d, n){
return sum + parseInt(((n + imei.length) %2)? d: [0,2,4,6,8,1,3,5,7,9][d]);
}, 0)) % 10 == 0;
};
Works fine for both CC and IMEI numbers. Fiddle: http://jsfiddle.net/8VqpN/
Lookup tables or arrays can simplify algorithm implementations - save many lines of code - and with that increase performance... if the calculation of the lookup index is simple - or simpler - and the array's memory footprint is affordable.
On the other hand, understanding how the particular lookup array or data structure came to be can at times be quite difficult, because the related algorithm implementation may look - at first sight - quite different from the original algorithm specification or description.
Indication to use lookup tables are number oriented algorithms with simple arithmetics, simple comparisons, and equally structured repetition patterns - and of course - of quite finite value sets.
The many answers in this thread go for different lookup tables and with that for different algorithms to implement the very same Luhn algorithm. Most implementations use the lookup array to avoid the cumbersome figuring out of the value for doubled digits:
var luhnArr = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
//
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
// | | | | | | | | | |
//
// - d-igit=index: 0 1 2 3 4 5 6 7 8 9
// - 1st
// calculation: 2*0 2*2 2*2 2*3 2*4 2*5 2*6 2*7 2*8 2*9
// - intermeduate
// value: = 0 = 2 = 4 = 6 = 8 =10 =12 =14 =16 =18
// - 2nd
// calculation: 1+0 1+2 1+4 1+6 1+8
//
// - final value: 0 2 4 6 8 =1 =3 =5 =7 =9
//
var luhnFinalValue = luhnArray[d]; // d is numeric value of digit to double
An equal implementation for getting the luhnFinalValue looks like this:
var luhnIntermediateValue = d * 2; // d is numeric value of digit to double
var luhnFinalValue = (luhnIntermediateValue < 10)
? luhnIntermediateValue // (d ) * 2;
: luhnIntermediateValue - 10 + 1; // (d - 5) * 2 + 1;
Which - with the comments in above true and false terms - is of course simplified:
var luhnFinalValue = (d < 5) ? d : (d - 5) * 2 + 1;
Now I'm not sure if I 'saved' anything at all... ;-) especially thanks the value-formed or short form of if-then-else. Without it, the code may look like this - with 'orderly' blocks
and embedded in the next higher context layer of the algorithm and therefore luhnValue:
var luhnValue; // card number is valid when luhn values for each digit modulo 10 is 0
if (even) { // even as n-th digit from the the end of the string of digits
luhnValue = d;
} else { // doubled digits
if (d < 5) {
luhnValue = d * 2;
} else {
lunnValue = (d - 5) * 2 + 1;
}
}
Or:
var luhnValue = (even) ? d : (d < 5) ? d * 2 : (d - 5) * 2 + 1;
Btw, with modern, optimizing interpreters and (just in time) compilers, the difference is only in the source code and matters only for readability.
Having come that far with explanation - and 'justification' - of the use of lookup tables and comparison to straight forward coding, the lookup table looks now a bit overkill to me. The algorithm without is now quite easy to finish - and it looks pretty compact too:
function luhnValid(cardNo) { // cardNo as a string w/ digits only
var sum = 0, even = false;
cardNo.split("").reverse().forEach(function(dstr){ d = parseInt(dstr);
sum += ((even = !even) ? d : (d < 5) ? d * 2 : (d - 5) * 2 + 1);
});
return (sum % 10 == 0);
}
What strikes me after going through the explanation exercise is that the initially most enticing implementation - the one using reduce() from #kalypto - just lost totally its luster for me... not only because it is faulty on several levels, but more so because it shows that bells and whistles may not always 'ring the victory bell'. But thank you, #kalypto, it made me actually use - and understand - reduce():
function luhnValid2(cardNo) { // cardNo as a string w/ digits only
var d = 0, e = false; // e = even = n-th digit counted from the end
return ( cardNo.split("").reverse().reduce(
function(s,dstr){ d = parseInt(dstr); // reduce arg-0 - callback fnc
return (s + ((e = !e) ? d : [0,2,4,6,8,1,3,5,7,9][d]));
} // /end of callback fnc
,0 // reduce arg-1 - prev value for first iteration (sum)
) % 10 == 0
);
}
To be true to this thread, some more lookup table options have to be mentioned:
how about just adjust varues for doubled digits - as posted by #yngum
how about just everything with lookup tables - as posted by #Simon_Weaver - where also the values for the non-doubled digits are taken from a look up table.
how about just everything with just ONE lookup table - as inspired by the use of an offset as done in the extensively discussed luhnValid() function.
The code for the latter - using reduce - may look like this:
function luhnValid3(cardNo) { // cardNo as a string w/ digits only
var d = 0, e = false; // e = even = n-th digit counted from the end
return ( cardNo.split("").reverse().reduce(
function(s,dstr){ d = parseInt(dstr);
return (s + [0,1,2,3,4,5,6,7,8,9,0,2,4,6,8,1,3,5,7,9][d+((e=!e)?0:10)]);
}
,0
) % 10 == 0
);
}
And for closing lunValid4() - very compact - and using just 'old fashioned' (compatible) JavaScript - with one single lookup table:
function luhnValid4(cardNo) { // cardNo as a string w/ digits only
var s = 0, e = false, p = cardNo.length; while (p > 0) { p--;
s += "01234567890246813579".charAt(cardNo.charAt(p)*1 + ((e=!e)?0:10)) * 1; }
return (s % 10 == 0);
}
Corollar: Strings can be looked at as lookup tables of characters... ;-)
A perfect example of a nice lookup table application is the counting of set bits in bits lists - bits set in a a (very) long 8-bit byte string in (an interpreted) high-level language (where any bit operations are quite expensive). The lookup table has 256 entries. Each entry contains the number of bits set in an unsigned 8-bit integer equal to the index of the entry. Iterating through the string and taking the unsigned 8-bit byte equal value to access the number of bits for that byte from the lookup table. Even for low-level language - such as assembler / machine code - the lookup table is the way to go... especially in an environment, where the microcode (instruction) can handle multiple bytes up to 256 or more in an (single CISC) instruction.
Some notes:
numberString * 1 and parseInt(numberStr) do about the same.
there are some superfluous indentations, parenthesis,etc... supporting my brain in getting the semantics quicker... but some that I wanted to leave out, are actually required... when
it comes to arithmetic operations with short-form, value-if-then-else expressions as terms.
some formatting may look new to you; for examples, I use the continuation comma with the
continuation on the same line as the continuation, and I 'close' things - half a tab - indented to the 'opening' item.
All formatting is all done for the human, not the computer... 'it' does care less.
algorithm datastructure luhn lookuptable creditcard validation bitlist
A very fast and elegant implementation of the Luhn algorithm following:
const isLuhnValid = function luhn(array) {
return function (number) {
let len = number ? number.length : 0,
bit = 1,
sum = 0;
while (len--) {
sum += !(bit ^= 1) ? parseInt(number[len], 10) : array[number[len]];
}
return sum % 10 === 0 && sum > 0;
};
}([0, 2, 4, 6, 8, 1, 3, 5, 7, 9]);
console.log(isLuhnValid("4112344112344113".split(""))); // true
console.log(isLuhnValid("4112344112344114".split(""))); // false
On my dedicated git repository you can grab it and retrieve more info (like benchmarks link and full unit tests for ~50 browsers and some node.js versions).
Or you can simply install it via bower or npm. It works both on browsers and/or node.
bower install luhn-alg
npm install luhn-alg
If you want to calculate the checksum, this code from this page is very concise and in my random tests seems to work.
NOTE: the verification algorithmns on this page do NOT all work.
// Javascript
String.prototype.luhnGet = function()
{
var luhnArr = [[0,1,2,3,4,5,6,7,8,9],[0,2,4,6,8,1,3,5,7,9]], sum = 0;
this.replace(/\D+/g,"").replace(/[\d]/g, function(c, p, o){
sum += luhnArr[ (o.length-p)&1 ][ parseInt(c,10) ]
});
return this + ((10 - sum%10)%10);
};
alert("54511187504546384725".luhnGet());​
Here's my findings for C#
function luhnCheck(value) {
return 0 === (value.replace(/\D/g, '').split('').reverse().map(function(d, i) {
return +['0123456789','0246813579'][i % 2][+d];
}).reduce(function(p, n) {
return p + n;
}) % 10);
}
Update: Here's a smaller version w/o string constants:
function luhnCheck(value) {
return !(value.replace(/\D/g, '').split('').reverse().reduce(function(a, d, i) {
return a + d * (i % 2 ? 2.2 : 1) | 0;
}, 0) % 10);
}
note the use of 2.2 here is to make doubling d roll over with an extra 1 when doubling 5 to 9.
Code is the following:
var LuhnCheck = (function()
{
var luhnArr = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
return function(str)
{
var counter = 0;
var incNum;
var odd = false;
var temp = String(str).replace(/[^\d]/g, "");
if ( temp.length == 0)
return false;
for (var i = temp.length-1; i >= 0; --i)
{
incNum = parseInt(temp.charAt(i), 10);
counter += (odd = !odd)? incNum : luhnArr[incNum];
}
return (counter%10 == 0);
}
})();
The variable counter is the sum of all the digit in odd positions, plus the double of the digits in even positions, when the double exceeds 10 we add the two numbers that make it (ex: 6 * 2 -> 12 -> 1 + 2 = 3)
The Array you are asking about is the result of all the possible doubles
var luhnArr = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
0 * 2 = 0 --> 0
1 * 2 = 2 --> 2
2 * 2 = 4 --> 4
3 * 2 = 6 --> 6
4 * 2 = 8 --> 8
5 * 2 = 10 --> 1+0 --> 1
6 * 2 = 12 --> 1+2 --> 3
7 * 2 = 14 --> 1+4 --> 5
8 * 2 = 16 --> 1+6 --> 7
9 * 2 = 18 --> 1+8 --> 9
So for example
luhnArr[3] --> 6 (6 is in 3rd position of the array, and also 3 * 2 = 6)
luhnArr[7] --> 5 (5 is in 7th position of the array, and also 7 * 2 = 14 -> 5 )
Another alternative:
function luhn(digits) {
return /^\d+$/.test(digits) && !(digits.split("").reverse().map(function(checkDigit, i) {
checkDigit = parseInt(checkDigit, 10);
return i % 2 == 0
? checkDigit
: (checkDigit *= 2) > 9 ? checkDigit - 9 : checkDigit;
}).reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
}) % 10);
}
Alternative ;) Simple and Best
<script>
// takes the form field value and returns true on valid number
function valid_credit_card(value) {
// accept only digits, dashes or spaces
if (/[^0-9-\s]+/.test(value)) return false;
// The Luhn Algorithm. It's so pretty.
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
console.log(valid_credit_card("5610591081018250"),"valid_credit_card Validation");
</script>
Best Solution here
http://plnkr.co/edit/34aR8NUpaKRCYpgnfUbK?p=preview
with all test cases passed according to
http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
and the credit goes to
https://gist.github.com/DiegoSalazar/4075533
const LuhnCheckCard = (number) => {
if (/[^0-9-\s]+/.test(number) || number.length === 0)
return false;
return ((number.split("").map(Number).reduce((prev, digit, i) => {
(!(( i & 1 ) ^ number.length)) && (digit *= 2);
(digit > 9) && (digit -= 9);
return prev + digit;
}, 0) % 10) === 0);
}
console.log(LuhnCheckCard("4532015112830366")); // true
console.log(LuhnCheckCard("gdsgdsgdsg")); // false
I worked out the following solution after I submitted a much worse one for a test..
function valid(number){
var splitNumber = parseInt(number.toString().split(""));
var totalEvenValue = 0;
var totalOddValue = 0;
for(var i = 0; i < splitNumber.length; i++){
if(i % 2 === 0){
if(splitNumber[i] * 2 >= 10){
totalEvenValue += splitNumber[i] * 2 - 9;
} else {
totalEvenValue += splitNumber[i] * 2;
}
}else {
totalOddValue += splitNumber[i];
}
}
return ((totalEvenValue + totalOddValue) %10 === 0)
}
console.log(valid(41111111111111111));
I recently wrote a solution using Javascript, I leave the code here for anyone who can help:
// checksum with Luhn Algorithm
const luhn_checksum = function(strIn) {
const len = strIn.length;
let sum = 0
for (let i = 0; i<10; i += 1) {
let factor = (i % 2 === 1) ? 2: 1
const v = parseInt(strIn.charAt(i), 10) * factor
sum += (v>9) ? (1 + v % 10) : v
}
return (sum * 9) % 10
}
// teste exampple on wikipedia:
// https://en.wikipedia.org/wiki/Luhn_algorithm
const strIn = "7992739871"
// The checksum of "7992739871" is 3
console.log(luhn_checksum(strIn))
If you understand this code above, you will have no problem converting it to any other language.
For example in python:
def nss_checksum(nss):
suma = 0
for i in range(10):
factor = 2 if (i % 2 == 1) else 1
v = int(nss[i]) * factor
suma += (1 + v % 10) if (v >9) else v
return (suma * 9) % 10
For more info, check this:
https://en.wikipedia.org/wiki/Luhn_algorithm
My Code(En español):
https://gist.github.com/fitorec/82a3e27fae3bab709a07c19c71c3a8d4
def validate_credit_card_number(card_number):
if(len(str(card_number))==16):
group1 = []
group1_double = []
after_group_double = []
group1_sum = 0
group2_sum = 0
group2 = []
total_final_sum = 0
s = str(card_number)
list1 = [int(i) for i in list(s)]
for i in range(14, -1, -2):
group1.append(list1[i])
for x in group1:
b = 0
b = x * 2
group1_double.append(b)
for j in group1_double:
if(j > 9):
sum_of_digits = 0
alias = str(j)
temp1 = alias[0]
temp2 = alias[1]
sum_of_digits = int(temp1) + int(temp2)
after_group_double.append(sum_of_digits)
else:
after_group_double.append(j)
for i in after_group_double:
group1_sum += i
for i in range(15, -1, -2):
group2.append(list1[i])
for i in group2:
group2_sum += i
total_final_sum = group1_sum + group2_sum
if(total_final_sum%10==0):
return True
else:
return False
card_number= 1456734512345698 #4539869650133101 #1456734512345698 # #5239512608615007
result=validate_credit_card_number(card_number)
if(result):
print("credit card number is valid")
else:
print("credit card number is invalid")

Categories

Resources