読者です 読者をやめる 読者になる 読者になる

モジュラス11ウェイト2~7(M11W2~7)実装してみる

Java

モジュラス11ウェイト2~7(M11W2~7)とは、以下の計算式でチェックディジット等で使用されます。
モジュラス10もあるけど、あっちは古いので11にする。

[計算式]
1.データの末尾の桁からウエイトを2.3.4.…7.とかけてゆき、総和を求めます。
  ※ウエイトが7を越えるときは、再び2.から3.4.とかけていきます。
2.総和を"11"で割りその 余りを求めます。
3."11"より余りを引いた値がチェックデジットとなります。
 ※余りが0の場合はチェックデジット「0」
 ※余りが1の場合はチェックデジット「0」 

【例】
12345678の場合
1.(8×2)+(7×3)+(6×4)+(5×5)+(4×6)+(3×7)+(2×2)+(1×3)=16+21+24+25+24+21+4+3=138
2.138/11=12 余り6
3.11-6=5 チェックデジット「5」

どっかに実装があるかと思って探したけど無さそうなので作る

Test

public class CheckDigitUtilTest extends TestCase {
    public void testMojuras11() throws Exception {
        assertEquals(2, CheckDigitUtil.mojuras11(123456789));
        assertEquals(1, CheckDigitUtil.mojuras11(987654321));
        assertEquals(6, CheckDigitUtil.mojuras11(4444333999999999L));
    }
}
public class CheckDigitUtil {
    private static final int MOJURAS11_MAX_WEIGHT = 7;
    private static final int MOJURAS11_MIN_WEIGHT = 2;
    private static final int MOJURAS11_MOJURAS_VALUE = 11;
    public static int mojuras11(long n) {
        int sum = 0;
        int x = MOJURAS11_MIN_WEIGHT;
        do {
            sum += ((n % 10) * x);
            x = (MOJURAS11_MAX_WEIGHT == x) ? MOJURAS11_MIN_WEIGHT : ++x;
        } while ((n = n / 10) != 0); 
        int mod = sum % MOJURAS11_MOJURAS_VALUE;
        return (mod == 1) ? 0 : MOJURAS11_MOJURAS_VALUE - mod;
    }
}

どう書く?orgにあるかと思って探したけど無かったです。
他の言語だともっと短く出来るのかな。

※余りが0の場合の考慮漏れを"ょこたん"から指摘ありました