Created
November 11, 2015 13:33
-
-
Save ytkhs/004a1a8fba6ea04047f8 to your computer and use it in GitHub Desktop.
マイナンバーのチェックデジットをGoで計算する ref: http://qiita.com/qube81/items/f66a38b28ec58bc5c4da
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ go run mynumber.go | |
> true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ go test -v | |
=== RUN TestValidateMyNumber | |
--- PASS: TestValidateMyNumber (0.00s) | |
PASS | |
ok mynumber 0.006s |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"regexp" | |
"strconv" | |
"unicode/utf8" | |
) | |
func main() { | |
// 有効なマイナンバーです | |
r := validateMyNumber("123456789018") | |
fmt.Println(r) | |
} | |
func validateMyNumber(numstr string) bool { | |
// 12文字かどうか | |
if utf8.RuneCountInString(numstr) != 12 { | |
return false | |
} | |
// 全て数字かどうか | |
if !regexp.MustCompile(`^[0-9]+$`).Match([]byte(numstr)) { | |
return false | |
} | |
// 最後の一桁をチェックデジットとする | |
checkDigit, _ := strconv.Atoi(numstr[11:]) | |
// 残り11けたを逆順にします | |
runes := []rune(numstr[:11]) | |
for i, j := 0, 11-1; i < j; i, j = i+1, j-1 { | |
runes[i], runes[j] = runes[j], runes[i] | |
} | |
// 1文字ずつ処理します | |
pq := 0 | |
for i, r := range runes { | |
// 何番目か | |
n := i + 1 | |
// Pn | |
p, _ := strconv.Atoi(string(r)) | |
// Qn | |
var q int | |
if n >= 7 { | |
q = n - 5 | |
} else { | |
q = n + 1 | |
} | |
// Pn * Qn を足していきます | |
pq += p * q | |
} | |
// 条件でチェックデジットを検証します | |
remainder := pq % 11 | |
if remainder <= 1 { | |
return checkDigit == 0 | |
} | |
return checkDigit == (11 - remainder) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"testing" | |
) | |
func TestValidateMyNumber(t *testing.T) { | |
// 12桁以外が通ったらエラー | |
if validateMyNumber("1234567890120000000") { | |
t.Error("12桁でないものが通った") | |
} | |
// 半角数字以外が通ったらエラー | |
if validateMyNumber("I234S6789OI2") { | |
t.Error("数字以外が通った") | |
} | |
// 有効なマイナンバーがはじかれたら失敗 | |
if validateMyNumber("123456789018") == false { | |
t.Error("有効なものがはじかれた") | |
} | |
// 不正なものが通ってしまったら失敗 | |
if validateMyNumber("123456789010") { | |
t.Error("間違ってるものが通った") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment