マイナンバー（個人番号）の検査用数字の確認方法

マイナンバー（個人版号）は、12桁の数字で、下1桁は検査用数字です。
それは、次で定められています。
[総務省令第八十五号](https://www.soumu.go.jp/main_content/000327387.pdf)
PDF の 4,5ページです。

![p01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/063401e5-2129-c526-3174-d7673c7ee3b3.png)

![p02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/982792b6-2d3b-9149-7aa2-1a107a37f6fb.png)

## プログラム Python3

```py:check_digit.py
#! /usr/bin/python
#
#	check_digit.py
#
#					Feb/23/2024
import sys
#
# -------------------------------------------------------------------
def check_digit_proc(xin):
	rvalue = False
	dd = 100000000000
	bb = [6,5,4,3,2,7,6,5,4,3,2]
	check_digit = xin % 10
	print("input = %d" % xin)
	print("check_digit = %d" % check_digit)
	pp = 0
	for it in range(11):
		a = int (xin / dd)
		pp += a * bb[it]
		ab = int (xin % dd)
		xin = ab
		dd = dd / 10
#
	qq = pp % 11
	rr = 11 - qq
	ss = rr

	if 10 <= ss:
		ss = 0

	if check_digit == ss:
		rvalue = True
#
	return	rvalue
#
# -------------------------------------------------------------------
sys.stderr.write("*** start ***\n")
xin = int(sys.argv[1])

hantei = check_digit_proc(xin)

if hantei:
	sys.stderr.write("*** 正しい ***\n")
else:
	sys.stderr.write("*** 誤り ***\n")
	
sys.stderr.write("*** end ***\n")
# -------------------------------------------------------------------
```

実行結果

```text
$ ./check_digit.py 983205673214
*** start ***
input = 983205673214
check_digit = 4
*** 正しい ***
*** end ***

$ ./check_digit.py 983205673210
*** start ***
input = 983205673210
check_digit = 0
*** 誤り ***
*** end ***
```

確認したバージョン

```text
$ python --version
Python 3.11.6
```

## プログラム　Node.js

```js:check_digit.js
#! /usr/local/bin/node
//
//	check_digit.js
//					Feb/23/2024
//
// ---------------------------------------------------------------
function check_digit_proc(xin)
{
	var rvalue = false
	var dd = 100000000000
	const bb = [6,5,4,3,2,7,6,5,4,3,2]
	const check_digit = xin % 10
	console.log("input = " , xin)
	console.log("check_digit = " , check_digit)
	var pp = 0
	for (var it=0; it<11; it += 1)
		{
		var a = Math.trunc(xin / dd)
		pp += a * bb[it]
		xin = Math.trunc(xin % dd)
		dd = dd / 10
		}
	var qq = pp % 11
	var rr = 11 - qq
	var ss = rr
	if (10 <= ss)
		{
		ss = 0
		}

	if (check_digit == ss)
		{
		rvalue = true
		}

	return rvalue
}

// ---------------------------------------------------------------
console.error("*** start ***")
var xin = process.argv[2]



hantei = check_digit_proc(xin)


if (hantei)
	console.error("*** 正しい ***")
else
	console.error("*** 誤り ***")
	
console.error("*** end ***")
// ---------------------------------------------------------------
```

実行結果

```text
$ ./check_digit.js 983205673214
*** start ***
input =  983205673214
check_digit =  4
*** 正しい ***
*** end ***

$ ./check_digit.js 983205673210
*** start ***
input =  983205673210
check_digit =  0
*** 誤り ***
*** end ***
```

確認したバージョン

```text
$ node --version
v19.6.0
```

## プログラム　Deno

```ts:check_digit.ts
//
//	check_digit.ts
//					Feb/23/2024
//
// ---------------------------------------------------------------
function check_digit_proc(xin): boolean
{
	let rvalue = false
	let dd:number = 100000000000
	const bb:number = [6,5,4,3,2,7,6,5,4,3,2]
	const check_digit:number = xin % 10
	console.log("input = " , xin)
	console.log("check_digit = " , check_digit)
	let pp:number = 0
	for (let it=0; it<11; it += 1)
		{
		let a:number = Math.trunc(xin / dd)
		pp += a * bb[it]
		xin = Math.trunc(xin % dd)
		dd = dd / 10
		}
	let qq:number = pp % 11
	let ss:number = 11 - qq
	if (10 <= ss)
		{
		ss = 0
		}


if (check_digit == ss)
	{
	rvalue = true
	}

	return rvalue
}

// ---------------------------------------------------------------
console.error("*** start ***")
let xin:number = Deno.args[0]

const hantei:boolean = check_digit_proc(xin)

if (hantei)
	console.error("*** 正しい ***")
else
	console.error("*** 誤り ***")
	
console.error("*** end ***")
// ---------------------------------------------------------------
```

実行結果

```text
$ deno run check_digit.ts 983205673214
*** start ***
input =  983205673214
check_digit =  4
*** 正しい ***
*** end ***

$ deno run check_digit.ts 983205673210
*** start ***
input =  983205673210
check_digit =  0
*** 誤り ***
*** end ***
```

確認したバージョン

```text
$ deno --version
deno 1.40.5 (release, x86_64-unknown-linux-gnu)
v8 12.1.285.27
typescript 5.3.3
```

## プログラム Ruby

```rb:check_digit.rb
#! /usr/bin/ruby
#
#	check_digit.rb
#
#					Feb/23/2024
#
# -------------------------------------------------------------------
def check_digit_proc(xin)
	rvalue = false
	dd = 100000000000
	bb = [6,5,4,3,2,7,6,5,4,3,2]
	check_digit = xin % 10
	print("input = %d\n" % xin)
	print("check_digit = %d\n" % check_digit)
	pp = 0
	for it in 0..10 do
		a = (xin / dd).to_i
		pp += a * bb[it]
		xin = xin % dd
		dd = dd / 10
	end
#
	qq = pp % 11
	rr = 11 - qq
	ss = rr

	if 10 <= ss then
		ss = 0
	end

	if check_digit == ss then
		rvalue = true
	end
#
	return	rvalue
#
end
#
# -------------------------------------------------------------------
STDERR.puts "*** start ***"
xin = ARGV[0].to_i

hantei = check_digit_proc(xin)

if hantei then
	STDERR.puts "*** 正しい ***"
else
	STDERR.puts "*** 誤り ***"
end
	
STDERR.puts	"*** end ***"
# -------------------------------------------------------------------
```

実行結果

```text
$ ./check_digit.rb 983205673214
*** start ***
input = 983205673214
check_digit = 4
*** 正しい ***
*** end ***

$ ./check_digit.rb 983205673210
*** start ***
input = 983205673210
check_digit = 0
*** 誤り ***
*** end ***
```

確認したバージョン

```text
$ ruby --version
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]
```

## プログラム Go
>次のプログラムは ChatGPT で変換しました。

```go:check_digit.go
//
//	check_digit.go
//					Feb/23/2024
//
// ---------------------------------------------------------------
package main

import (
	"fmt"
	"os"
	"strconv"
)

// ---------------------------------------------------------------
func checkDigitProc(xin int) bool {
	rvalue := false
	dd := 100000000000
	bb := []int{6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2}
	checkDigit := xin % 10
	fmt.Printf("input = %d\n", xin)
	fmt.Printf("check_digit = %d\n", checkDigit)
	pp := 0
	for it := 0; it < 11; it++ {
		a := xin / dd
		pp += a * bb[it]
		xin = xin % dd
		dd = dd / 10
	}

	qq := pp % 11
	ss := 11 - qq
	if 10 <= ss {
		ss = 0
	}

	if checkDigit == ss {
		rvalue = true
	}

	return rvalue
}

// ---------------------------------------------------------------
func main() {
	fmt.Fprintln(os.Stderr, "*** start ***")

	xin, err := strconv.Atoi(os.Args[1])
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	hantei := checkDigitProc(xin)

	if hantei {
		fmt.Fprintln(os.Stderr, "*** 正しい ***")
	} else {
		fmt.Fprintln(os.Stderr, "*** 誤り ***")
	}

	fmt.Fprintln(os.Stderr, "*** end ***")
}

// ---------------------------------------------------------------
```

実行結果

```text
$ go run check_digit.go 983205673214
*** start ***
input = 983205673214
check_digit = 4
*** 正しい ***
*** end ***
uchida@shimizu: golang$ go run check_digit.go 983205673210
*** start ***
input = 983205673210
check_digit = 0
*** 誤り ***
*** end ***
```

確認したバージョン

```text
$ go version
go version go1.21.1 linux/amd64
```

## 住民票コード

マイナンバーは、住民票コードから作成されています。
住民票コードは　10桁　+ 検査用数字1桁　の 11桁
マイナンバーは　11桁　+ 検査用数字1桁　の 12桁

住民票コード の検査用数字も、マイナンバーと同じ方法で計算ができます。

参考ページ
[[メモ] 各種チェックデジットの計算方法](https://qiita.com/yoshi389111/items/00ca7b3ed9ceac904cde)