-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathluhn.go
47 lines (44 loc) · 1.52 KB
/
luhn.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//
// Copyright (C) 2020 Diego Augusto Molina
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// This package efficiently implements the Luhn Algorithm
//
package goluhn
// LuhnValidate returns whether the supplied string represents a valid string of
// digits validated with the Luhn Algorithm by the rightmost digit
func LuhnValidate(str string) bool {
l := len(str) - 1
return l > 0 && LuhnChecksum(str[:l]) == str[l:]
}
// LuhnChecksum calculates the Luhn verification digit fot a string containing a
// series of digits. If the string contains any non-digit character it returns
// an empty string
func LuhnChecksum(str string) string {
var sum uint
p := ^len(str) & 0x1
for i, r := range str {
// Convert to number and check if the supplied values are not digits
if r -= '0'; uint(r) > 9 {
return ""
}
if i&p != 0 { // Double the number in case of even iteration
if r <<= 1; r > 9 {
r -= 9 // Sum the digits
}
}
sum += uint(r)
}
return string((sum*9)%10 + '0')
}