0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Luhnアルゴリズム(ルーンアルゴリズム)のチェックディジットの部分を算出する

Last updated at Posted at 2019-09-25

概要

Luhnアルゴリズム(ルーンアルゴリズム)のチェックディジットの部分を算出する。
※確認したのは15桁の数値に対してのみ。

15桁の数字が、
846087729128569 の場合、7 がチェックディジットになる。
545762389823411 の場合、3 がチェックディジットになる。

実装

パワープレイしてるところあるけど気にしない方向で。。
色んな言語に移植しやすいはず、逆にね、、

php
/*
 * 15桁の数値に対して、チェックディジットとして付与するべき数字を算出する。
 * ※15桁じゃなくても多分大丈夫だけど、15桁以外は試してない
 */
function gen_checkdigit($num)
{

    // ルーン・アルゴリズムの参考サイト
    // https://www.gizmodo.jp/2013/07/post_12829.html
    // https://qiita.com/yossyyossy/items/41369a37ba05dccf53a9

    // チェックディジットを計算するために15桁を16桁に上げる
    // ※1桁目が0になるようにする(1桁目をxにする)ために10を掛ける
    // ※感覚としては、15桁の数字が 846087729128569 の場合、 846087729128569X という状態にする。
    $num = $num * 10;

    // 数値を文字配列へ変換する。
    // 数値が 8460877291285690 の場合、
    // 先頭(8)が$num_array[0]で、最後(0)が$num_array[15]
    $num_array = str_split($num);

    $kisu = 0;
    // 奇数桁の計算。奇数桁の和を求める。
    // この時点では1桁目(チェックディジット)は必ず0で、処理の最後にチェックディジットとして正しい数値を出す。
    for ($idx = 1; $idx < sizeof($num_array); $idx += 2) {
        $kisu += $num_array[$idx];
    }

    $gusu = 0;
    // 偶数桁の計算。
    // 偶数桁は2倍にする。ただし、2倍して2桁になる数字は1桁目と2桁目の和を使う。
    for ($idx = 0; $idx < sizeof($num_array); $idx += 2) {

        // 5*2 は 10 なので 1(1+0) を足す
        // 6*2 は 12 なので 3(1+2) を足す
        // 7*2 は 14 なので 5(1+4) を足す
        // 8*2 は 16 なので 7(1+6) を足す
        // 9*2 は 18 なので 9(1+8) を足す
        // 2倍にして2桁にならない数は2倍した数値を足す
        if ($num_array[$idx] == 5) {
            $gusu += 1;
        } else if ($num_array[$idx] == 6) {
            $gusu += 3;
        } else if ($num_array[$idx] == 7) {
            $gusu += 5;
        } else if ($num_array[$idx] == 8) {
            $gusu += 7;
        } else if ($num_array[$idx] == 9) {
            $gusu += 9;
        } else {
            $gusu += $num_array[$idx] * 2;
        }
    }

    // 上でやっている (奇数桁の和+偶数桁の和) % 10 が 0 となる場合、正しい番号となる。
    // ※この時点では1桁目が 0 で固定なので、ほぼ正しくない番号
    // (奇数桁の和+偶数桁の和)+ X(1桁目)) % 10 が 0 となる X を求めると、
    // X がチェックディジットとして、1桁目に付与する数値となる。
    $_ = $kisu + $gusu;
    $digit = 0;
    while (true) {
        // 10で割り切れた時、breakする
        if (($_ + $digit) % 10 == 0) {
            break;
        } else {
            // 10で割り切れるまで、カウントアップし続ける
            $digit++;
        }
    }

    return $digit;
}

参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?