Fortran タグで下記記事が流れてきたので、遅ればせながら日曜午後の暇つぶしにと参加してみました。
色々な言語でマイナンバーのチェックデジットを計算したかった
計算方法などは、以下を参照しました。
マイナンバーのチェックデジットを計算する - Qiita
ソース・プログラム
Fortran 2003 なのはコマンドライン引数を取るところだけで、残りは Fortran90/95 水準です。
module m_mynum
implicit none
contains
pure integer function ichk_sum(ip)
integer, intent(in) :: ip(11)
integer :: i, iq(11)
forall (i = 1:11) iq(i) = mod(i - 1, 6) + 2
ichk_sum = 11 - mod(sum(ip * iq), 11)
if (ichk_sum >= 10) ichk_sum = 0
end function ichk_sum
subroutine chk_mynumber(c)
character, intent(in) :: c(12)
integer :: m(12)
m = iachar(c) - iachar('0') ! change to ascii code
if (m(12) == ichk_sum( m(11:1:-1) )) then ! reverse order
print *, 'check matched!'
else
print *, 'check failed!'
end if
end subroutine chk_mynumber
end module m_mynum
program mynum
use m_mynum
implicit none
character (len = 80) :: buff
call get_command_argument(1, buff) ! F2003
if (len_trim(buff) == 12) then
call chk_mynumber(transfer(buff, ' ', size = 12)) ! string to chr-array
else
print *, 'input must be 12 digits long'
end if
end program mynum
チェックサム関数の pure プレフィックスは、今の場合ただの飾りです。
Transfer 関数で文字列を、文字配列に直しています。文字配列にすると、関数の elemental な性質が使えるのでループ変数で回す必要がなくなります。intel 拡張の [1:11] での数列生成を用いれば、forall ループもいらなくなるのですが、ここは標準に敬意を払って・・・
ichar と iachar の違いは、処理系の文字コードか ASCII コードかの違いです。Fortran 界では長年 IBM の EBCDIC が正字だったので二通りの関数が用意してあります。現在では ASCII に一統された感があるので、あまり気にしなくても問題ありません。EBCDIC では文字が連続して並んでいないので、文字コードの連続性を仮定した ASCII コードでのテクニックがしばしば破綻します。
###実行結果
E:\Projects\Console4\mynum\Debug>mynum 12345678901
input must be 12 digits long
E:\Projects\Console4\mynum\Debug>mynum 123456789010
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789011
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789012
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789013
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789014
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789015
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789016
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789017
check failed!
E:\Projects\Console4\mynum\Debug>mynum 123456789018
check matched!
E:\Projects\Console4\mynum\Debug>mynum 123456789019
check failed!