# Implementing Luhn's Algo in Solidity?

Is it possible (I believe so, especially with strings.lib) to implement Luhn's Algorithm (the math function that confirms all 16 digits of a credit card are valid) in a solidity function without severe gas costs for strings manipulations?

Here is a js example of Luhn's Algo - I'm a bit lost on best place to start in solidity.

``````// Takes a credit card string 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.
let nCheck = 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 && (nDigit *= 2) > 9) nDigit -= 9;

nCheck += nDigit;
bEven = !bEven;
}

return (nCheck % 10) == 0;
}
``````

Questions I have:

• String, bytes, or uint? (for gas costs)
• Assembly or string library? (for gas costs)
• optimization of math functions for gas
• Anyway to not use a loop?

Would love to see some starting points if anyone has any ideas

i have implemented a slim version which does not check the input for the correct format. it just expect numbers like 49927398716 or 1234567812345670. also, you pass the number as a sequence of bytes. by example if you want to check:

• "49927398716" you need to pass "0x0409090207030908070106"

• "1234567812345670" you need to pass "0x01020304050607080102030405060700"

`````` function valid_credit_card(bytes memory value) external returns (bool){
// The Luhn Algorithm. It's so pretty.
uint256 nCheck = 0;
bool bEven = false;

for (uint256 n = value.length; n > 0; n--) {
uint256 nDigit = uint256(uint8(value[n-1]));
if (bEven && (nDigit *= 2) > 9) nDigit -= 9;

nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
``````

I convert your code into solidity language.

``````//SPDX-License-Identifier: MIT

pragma solidity >0.8.1;

contract Luhn {

/// @title Lunh Algorithim implementation
/// @author Atarpara
/// @notice is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, Canadian Social Insurance Numbers.
/// @return ture or false
function luhnalgo(string calldata _number) public pure returns(bool){
bytes memory c = bytes(_number);
uint length = c.length;
uint8 sum = 0;
uint8 zero = 48;
bool _a = false;

for(uint i = length ; i > 0 ; i--){
uint8 temp = uint8(c[i-1]);

if(temp < 47  && temp > 58){