LoginSignup
3
0

More than 5 years have passed since last update.

C++で12桁のチェックデジット計算を書いてみた

Posted at

はじめに

ちょっと色々あって12桁の数字にチェックデジットを付与することになった。
その時に書いたコードの覚書。

チェックデジット計算方法

チェックデジットの計算方法としてはモジュラス10 ウェイト2・1分割(Luhn formula)を使用。

こちらの記事を参考にさせていただいた。
https://qiita.com/yoshi389111/items/00ca7b3ed9ceac904cde

実際のコード

で、書いたコードはこちら
https://wandbox.org/permlink/eSXajf2vfO8UvJMp

以下、コードの解説

12桁の数字の数が何件あるか不明だったので std::vector<std::string> で動的配列を確保。


//番号格納配列
std::vector<std::string> Num;

次に、確保した動的配列 Num に12桁の数字データを格納する関数 NumberRead を書いた。


//番号読み取り関数
//NumberRead
void NumberRead(){

    //カード番号を配列に格納
    for(std::string num; std::getline(std::cin, num); )
        Num.emplace_back(std::move(num));
}

for で回しておいて std::getline(std::cin, num) で入力されたデータを確保。
その後、 Num.emplace_back(std::move(num)) で配列に格納していく。

で、チェックデジットを計算して、元々の12桁と一緒に出力する関数 NumberWrite を書いた。
この辺は、ちょろっと書くのに手間がかかったかな……?


//チェックデジット書き込み関数
//NumberWrite
void NumberWrite(){

    //格納されている番号分だけループ
    for(auto&& d : Num){

        //番号を一時的に格納する変数
        int digit[12];

        //チェックデジット計算変数
        int temp = 0;

        //番号を一桁ずつ格納
        for(int i = 0; i < 12; i++)
            digit[i] = static_cast<int>(d[i]) - 48;

        //桁数分、チェックデジット用の計算を行う
        for(int j = 0; j < 12; j++){
            if((j + 1) % 2 == 0){
                if((digit[j] * 2) > 9)
                    temp += (((digit[j] * 2) % 10) + 1);
                else
                    temp += (digit[j] * 2);         
            } else
                temp += digit[j];
        }
        int t = (10 - (temp % 10));
        //番号とチェックデジットを表示
        std::cout << d << ((t == 10)? 0 : t) << std::endl;
    }
}

for(auto&& d : Num) はC++11で追加された範囲for文(The range-based for statement)というものになる。
これを使って Num に格納されたデータを一つずつ d に渡していく。
ちなみに、この範囲for文(The range-based for statement)は C++ でコンテナを使ったループを書くときに重宝するので、覚えておいて損はないね。

詳しい解説はこちらを参照されたし
https://cpprefjp.github.io/lang/cpp11/range_based_for.html


//番号を一桁ずつ格納
for(int i = 0; i < 12; i++)
     digit[i] = static_cast<int>(d[i]) - 48;

for を使って一文字ずつ digit に格納。
そいで、格納したデータの型は文字列なので static_cast<int>int 型に変換。
int に変換すると 51 などの数値になるため、 -48 ですり合わせてる。


//桁数分、チェックデジット用の計算を行う
        for(int j = 0; j < 12; j++){
    if((j + 1) % 2 == 0){
       if((digit[j] * 2) > 9)
           temp += (((digit[j] * 2) % 10) + 1);
       else
             temp += (digit[j] * 2);         
    } else
                temp += digit[j];
}
int t = (10 - (temp % 10));
//番号とチェックデジットを表示
std::cout << d << ((t == 10)? 0 : t) << std::endl;

あとは、上記のコードでチェックデジットの計算を行って画面に出力するだけ

おわりに

今回は標準入力&標準出力を使ったけど、std::fstream を使えばCSV形式のファイルなんかでも処理ができると思う。
なので、業務なんかでチェックデジットの計算するって時には便利かもね。

参考記事

3
0
6

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
3
0