Skip to content

Instantly share code, notes, and snippets.

@ytkhs
Created November 11, 2015 13:33
Show Gist options
  • Save ytkhs/004a1a8fba6ea04047f8 to your computer and use it in GitHub Desktop.
Save ytkhs/004a1a8fba6ea04047f8 to your computer and use it in GitHub Desktop.
マイナンバーのチェックデジットをGoで計算する ref: http://qiita.com/qube81/items/f66a38b28ec58bc5c4da
$ go run mynumber.go
> true
$ go test -v
=== RUN TestValidateMyNumber
--- PASS: TestValidateMyNumber (0.00s)
PASS
ok mynumber 0.006s
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)
}
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