LuhnアルゴリズムをJavaで書いた
カドカワ祭りで買った『プログラマの考え方がおもしろいほど身につく本』に載っていたLuhnアルゴリズムをJavaで書いてみた。
Amazon.co.jp: カドカワ祭り: Kindleストア: 【ピックアップ】ライトノベル, 【ピックアップ】文芸, 【ピックアップ】実用・ビジネス・専門書, 【ピックアップ】コミック, 【ピックアップ】新書 など
後でエロい人が書いたコード*1を見ると、自分の糞コードっぷりがよくわかったが、後学のために晒す。
【お題】
元の数字の各桁に対して、1桁おきにその数字を2倍する。そのあとで、各桁の数字を足していく(2倍した結果2桁になる数字があれれば、十の位と一の位をそれぞれ個別に足す)。その合計が10で割り切れる場合、識別記号は妥当なものであるとみなす。
public class SampleLuhn { /** * チェックサム値の取得 * @param total 各桁の総和 * @return チェックサム値 */ private static int getCheckSum(int total) { int checkSum = 0; if(total % 10 != 0){ checkSum = 10 - (total % 10); } return checkSum; } /** * 引数の値を2倍した値を返却する(ただし2桁になった場合は各桁の数値を足した値を返却する) * @param target 処理対象の数値 * @return 第一引数の値を2倍した値 */ private static int doubleDigitValue(int target) { int doubleDigit = target * 2; if(doubleDigit >= 10){ return 1 + doubleDigit % 10; }else { return doubleDigit; } } /** * 第一引数の数値(偶数桁)における各桁の総和を返却する * @param target 処理対象の数値 * @param length 処理対象の数値の桁数 * @param power 処理対象の数値の累乗 * @return 第一引数における各数字の総和 */ private static int evenSum(int target, int length, int power) { // 総和 int total = 0; for (int i = 1; i <= length; i++) { System.out.println(i + "桁目は" + (target / power)); if(i%2 == 0){ // 偶数桁読み込み時 total += target / power; }else { // 奇数桁読み込み時 int doubleVal= doubleDigitValue(target / power); total += doubleVal; } target %= power; power /= 10; } System.out.println("総和 : " + total); return total; } /** * 第一引数の数値(奇数桁)における各桁の総和を返却する * @param target 処理対象の数値 * @param length 処理対象の数値の桁数 * @param power 処理対象の数値の累乗 * @return 第一引数における各数字の総和 */ private static int oddSum(int target, int length, int power) { // 総和 int total = 0; for (int i = 1; i <= length; i++) { System.out.println(i + "桁目は" + (target / power)); if(i%2 == 0){ // 偶数桁読み込み時 int doubleVal= doubleDigitValue(target / power); total += doubleVal; }else { // 奇数桁読み込み時 total += target / power; } target %= power; power /= 10; } System.out.println("総和 : " + total); return total; } /** * チェックサム値の取得 * @param target * @return チェックサム値 */ public static int createLohnCheckSum(int target) { // 桁数 int length = String.valueOf(target).length(); // 桁数に対する累乗 int power = (int)Math.pow(10, length - 1); // 総和 int sum = 0; // 桁数の偶数・奇数で場合分け if(length % 2 == 0){ sum = evenSum(target, length, power); }else { sum = oddSum(target, length, power); } // チェックサム値取得 int checkSum = getCheckSum(sum); return checkSum; } /** * mainメソッド * @param args */ public static void main(String[] args) { // チェック対象の数値 int target = 12345; // チェックサム作成 int checkSum = createLohnCheckSum(target); System.out.println("checksum : " + checkSum); } }
ちなみに参照実装は下記。エレガントだった。
http://www.chriswareham.demon.co.uk/software/Luhn.java
プログラマの考え方がおもしろいほど身につく本 問題解決能力を鍛えよう! (アスキー書籍)
- 作者: V.AntonSpraul,角征典,高木正弘
- 出版社/メーカー: KADOKAWA / アスキー・メディアワークス
- 発売日: 2014/08/14
- メディア: Kindle版
- この商品を含むブログ (3件) を見る