アルゴリズム

チェックデジット自動計算

① バーコードを入力してください。※チェックデジットを除く
② アルゴリズムを選択してください。
③ 「計算する」ボタンを押すと、チェックデジットを算出します。

  • ルーン・アルゴリズム
  • モジュラス10
  • モジュラス11
  • 数字チェック
  • モジュラス9
  • ISBN-10
  • モジュラス16
  • モジュラス43

Luhn algorithm、モジュラス10 ウェイト2・1分割
使用例:
・クレジットカード番号
・IMEI番号
・en: National Provider Identifier(アメリカでの医療機関の識別番号)
・カナダ社会保険番号(Social Insurance Number)
など

・重み=1をかけても元の数と変わらないので、奇数時のかけ算は省略できる。
・十の位と一の位を足した数と、元の数から9を引いた数は、同じ数字になる。
・重み=2なので、元の数が9*2=18以上にはなることはない。
・十の位と一の位に分割して足し算するより、元の数から9を引く方が簡潔。

101112131415161718
1+01+11+21+31+41 + 51+61+71+8
10-911-912-913-914-915-916-917-918-9
123456789
/// <summary>
/// モジュラス10 ウェイト2・1分割
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="evenWeight">重み(偶数)</param>
/// <param name="oddWeight">重み(奇数)</param>
/// <returns>チェックデジット</returns>
function luhnFormula(barcode, modulus, evenWeight, oddWeight) {
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    if (i % 2 == 0) {
      d *= evenWeight; // 重み(偶数)
    } else {
      d *= oddWeight; // 重み(奇数)
    }
    if (d > 9) {
      d -= 9;
    }
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  return cd;
}

別名:

  • モジュラス10

使用例:

  • モジュラス10、ウェイト3・1
    • ISBN-13(新体系、2007年~)
    • 一般的な商品のバーコード(JAN/EANなど)
    • 牛の個体識別番号

など

注意点:

  • 数字のみ
/// <summary>
/// モジュラス10 ウェイト2・1一括
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="evenWeight">重み(偶数)</param>
/// <param name="oddWeight">重み(奇数)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitModulus10(barcode, modulus, evenWeight, oddWeight) {
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    if (i % 2 == 0) {
      d *= evenWeight; // 重み(偶数)
    } else {
      d *= oddWeight; // 重み(奇数)
    }
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  return cd;
}

別名:

/// <summary>
/// モジュラス11
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="minWeight">重み(最小)</param>
/// <param name="maxWeight">重み(最大)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitModulus11(barcode, modulus, minWeight, maxWeight) {
  let barcodes = Array.from(barcode).reverse();
  let weight = minWeight;
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    d *= weight;
    sum += d;
    if (weight == maxWeight) {
      weight = minWeight;
    } else {
      weight++;
    }
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 1) {
    cd = modulus - remainder;
  }
  return cd;
}

別名:

  • セブンチェック
  • ナインチェック

使用例:

など

注意点:

  • 数字のみ
/// <summary>
/// セブンチェック(7DR及び7DSR)
/// ナインチェック(9DR及び9DSR)
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="weight">係数</param>
/// <param name="flg">フラグ</param>
/// <returns>チェックデジット</returns>
function numberCheck(barcode, weight, flg) {
  let cd = Number(barcode) % weight;
  if (flg == true) {
    cd = weight - cd;
  }
  return cd;
}

:モジュラス9ウェイト1・2
チェックデジットは先頭(左側)に付く。

  1. 偶数桁に、下の桁から順番に、1をかける。
  2. 奇数桁に、下の桁から順番に、2をかける。
  3. 各桁の結果の合計を求めます。
  4. 合計を9で割り、余りを求めます(モジュラス)。
  5. この余りを9から引いたもの(9 - 余り)がチェックデジットです。
/// <summary>
/// 法人番号(通称:法人用マイナンバー)のチェックデジット
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="evenWeight">重み(偶数)</param>
/// <param name="oddWeight">重み(奇数)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitModulus9(barcode, modulus, evenWeight, oddWeight) {
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    if (i % 2 == 0) {
      d *= evenWeight; // 重み(偶数)
    } else {
      d *= oddWeight; // 重み(奇数)
    }
    sum += d;
  }
  let cd = modulus - sum % modulus;
  return cd;
}

ISBN-10(2007年までの国際標準図書番号) :モジュラス11 ウェイト10-2

制限:数字のみ、10桁固定※チェックデジットを含む

  1. 下の桁から2~10の係数をかけていく。
  2. 各桁の結果を合計する。
  3. 合計を11で割り、余りを求める。
  4. (11 - 余り) = チェックデジット
  5. 結果 11(余り 0)の場合、チェックデジットは「0」
  6. 結果 10(余り 1)の場合、チェックデジットは「X」

備考:ISBNでは10をX、11を0と表記する。

/// <summary>
/// モジュラス11、ウェイト10~2
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="minWeight">重み(最小)</param>
/// <param name="maxWeight">重み(最大)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitISBN10(barcode, modulus, minWeight, maxWeight) {
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    d *= (minWeight + i);
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  if (cd == maxWeight) {
    cd = 'X';
  }
  return cd;
}

/// <summary>
/// モジュラス16
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <returns>チェックデジット</returns>
function modulusNumber16(barcode, modulus) {
  const chars = '0123456789-$:/.+ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  let barcodes = Array.from(barcode);
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = chars.indexOf(barcodes[i].toUpperCase());
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  return chars.charAt(cd);
}

/// <summary>
/// モジュラス43
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <returns>チェックデジット</returns>
function modulusNumber43(barcode, modulus) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%';
  let barcodes = Array.from(barcode);
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = chars.indexOf(barcodes[i].toUpperCase());
    sum += d;
  }
  let remainder = sum % modulus;
  let cd = chars.charAt(remainder);
  return cd;
}

ソースコード公開

<form>
<label for="barcode">バーコード(<span id="count">0</span>桁)※チェックデジットを除く</label>
<input type="text" name="barcode" id="barcode" placeholder="バーコードを入力してください。" oninput="count();" style="ime-mode: disabled;">
<label for="algorithm">アルゴリズム</label>
<select name="algorithm" id="algorithm">
<option value="">アルゴリズムを選択してください。</option>
<option value="LuhnFormula">モジュラス10 ウェイト2・1分割(Luhn Formula)</option>
<option value="M10W21">モジュラス10 ウェイト2・1一括</option>
<option value="M10W31">モジュラス10 ウェイト3・1</option>
<option value="M11W27">モジュラス11 ウェイト2~7</option>
<option value="M11W10">モジュラス11 ウェイト1~0</option>
<option value="7DR">セブンチェック(7DR)</option>
<option value="7DSR">セブンチェック(7DSR)</option>
<option value="9DR">ナインチェック(9DR)</option>
<option value="9DSR">ナインチェック(9DSR)</option>
<option value="MyNumber">法人番号(通称:法人用マイナンバー)のチェックデジット</option>
<option value="ISBN10">ISBN-10 のチェックデジット</option>
<option value="M16">モジュラス16(NW-7)</option>
<option value="M43">モジュラス43(CODE39)</option>
</select>
<input type="button" name="button" id="button" value="計算する" onclick="calc();">
<input type="reset" value="リセット" onclick="reset();">
<input type="text" name="cd" id="cd" maxlength="1" placeholder="チェックデジット" readonly>
</form>
<script>

/// <summary>
/// 画面ロード時
/// </summary>
window.onload = reset();

/// <summary>
/// 初期値リセット
/// </summary>
function reset() {
  const yyyymmdd = new Date().toLocaleDateString('sv-SE').replace(/-/g, '');
  document.getElementById('barcode').value = '';//yyyymmdd;
  document.getElementById('algorithm').value = '';
  document.getElementById('cd').value = '';
  document.getElementById('count').innerText= '0';
}

/// <summary>
/// 文字数カウント
/// </summary>
function count() {
  const barcode = document.getElementById('barcode').value;
  document.getElementById('count').innerText = barcode.length;
}

/// <summary>
/// チェックデジット計算
/// </summary>
function calc() {
  const barcode = document.getElementById('barcode').value;
  if (barcode.length == 0) {
    alert('バーコードを入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let cd = '';
  switch (document.getElementById('algorithm').value) {
    // モジュラス10、ウェイト2・1分割
    case 'LuhnFormula':
      cd = luhnFormula(barcode, 10, 2, 1);
      break;
    // モジュラス10、ウェイト2・1一括
    case 'M10W21':
      cd = getCheckDigitModulus10(barcode, 10, 2, 1);
      break;
    // モジュラス10、ウェイト3・1
    case 'M10W31':
      cd = getCheckDigitModulus10(barcode, 10, 3, 1);
      break;
    // モジュラス11、ウェイト2~7
    case 'M11W27':
      cd = getCheckDigitModulus11(barcode, 11, 2, 7);
      break;
    // モジュラス11、ウェイト1・0
    case 'M11W10':
      cd = getCheckDigitModulus11(barcode, 11, 1, barcode.length);
      break;
    // 7チェックDR
    case '7DR':
      cd = numberCheck(barcode, 7, false);
      break;
    // 7チェックDSR
    case '7DSR':
      cd = numberCheck(barcode, 7, true);
      break;
    // 9チェックDR
    case '9DR':
      cd = numberCheck(barcode, 9, false);
      break;
    // 9チェックDSR
    case '9DSR':
      cd = numberCheck(barcode, 9, true);
      break;
    // モジュラス9、ウェイト1・2
    case 'MyNumber':
      cd = getCheckDigitModulus9(barcode, 9, 1, 2);
      break;
    // モジュラス11、ウェイト2~10
    case 'ISBN10':
      cd = getCheckDigitISBN10(barcode, 11, 2, 10);
      break;
    // モジュラス16
    case 'M16':
      cd = modulusNumber16(barcode, 16);
      break;
    // モジュラス43
    case 'M43':
      cd = modulusNumber43(barcode, 43);
      break;
    // モジュラス103
    case 'M103':
      cd = modulusNumber(barcode, 103);
      break;
    // 未選択チェック
    default:
      alert('アルゴリズムを選択してください。');
      document.getElementById('algorithm').focus();
      break;
  }
  document.getElementById('cd').value = cd;
}

/// <summary>
/// モジュラス10 ウェイト2・1分割
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="evenWeight">重み(偶数)</param>
/// <param name="oddWeight">重み(奇数)</param>
/// <returns>チェックデジット</returns>
function luhnFormula(barcode, modulus, evenWeight, oddWeight) {
  // 数字チェック
  if (isNaN(barcode) == true) {
    alert('数字のみ入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    if (i % 2 == 0) {
      d *= evenWeight; // 重み(偶数)
    } else {
      d *= oddWeight; // 重み(奇数)
    }
    if (d > 9) {
      d -= 9;
    }
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  return cd;
}

/// <summary>
/// チェックデジット計算(モジュラス10)
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="evenWeight">重み(偶数)</param>
/// <param name="oddWeight">重み(奇数)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitModulus10(barcode, modulus, evenWeight, oddWeight) {
  // 数字チェック
  if (isNaN(barcode) == true) {
    alert('数字のみ入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    if (i % 2 == 0) {
      d *= evenWeight; // 重み(偶数)
    } else {
      d *= oddWeight; // 重み(奇数)
    }
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  return cd;
}

/// <summary>
/// チェックデジット計算(モジュラス11)
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="minWeight">重み(最小)</param>
/// <param name="maxWeight">重み(最大)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitModulus11(barcode, modulus, minWeight, maxWeight) {
  // 数字チェック
  if (isNaN(barcode) == true) {
    alert('数字のみ入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let barcodes = Array.from(barcode).reverse();
  let weight = minWeight;
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    d *= weight;
    sum += d;
    weight++;
    if (weight > maxWeight) {
      weight = minWeight;
    }
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 1) {
    cd = modulus - remainder;
  }
  return cd;
}

/// <summary>
/// セブンチェック(7DR及び7DSR)
/// ナインチェック(9DR及び9DSR)
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="weight">係数</param>
/// <param name="flg">フラグ</param>
/// <returns>チェックデジット</returns>
function numberCheck(barcode, weight, flg) {
  // 数字チェック
  if (isNaN(barcode) == true) {
    alert('数字のみ入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let cd = Number(barcode) % weight;
  if (flg == true) {
    cd = weight - cd;
  }
  return cd;
}

/// <summary>
/// 法人番号(通称:法人用マイナンバー)のチェックデジット
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="evenWeight">重み(偶数)</param>
/// <param name="oddWeight">重み(奇数)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitModulus9(barcode, modulus, evenWeight, oddWeight) {
  // 数字チェック
  if (isNaN(barcode) == true) {
    alert('数字のみ入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    if (i % 2 == 0) {
      d *= evenWeight; // 重み(偶数)
    } else {
      d *= oddWeight; // 重み(奇数)
    }
    sum += d;
  }
  let cd = modulus - sum % modulus;
  return cd;
}

/// <summary>
/// ISBN-10 のチェックデジット
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <param name="minWeight">重み(最小)</param>
/// <param name="maxWeight">重み(最大)</param>
/// <returns>チェックデジット</returns>
function getCheckDigitISBN10(barcode, modulus, minWeight, maxWeight) {
  // 数字チェック
  if (isNaN(barcode) == true) {
    alert('数字のみ入力してください。');
    document.getElementById('barcode').focus();
    return;
  }
  let barcodes = Array.from(barcode).reverse();
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = Number(barcodes[i]);
    d *= (i + minWeight);
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  if (cd == maxWeight) {
    cd = 'X';
  }
  return cd;
}

/// <summary>
/// モジュラス16
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <returns>チェックデジット</returns>
function modulusNumber16(barcode, modulus) {
  const chars = '0123456789-$:/.+ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  let barcodes = Array.from(barcode);
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = chars.indexOf(barcodes[i].toUpperCase());
    sum += d;
  }
  let cd = 0;
  let remainder = sum % modulus;
  if (remainder > 0) {
    cd = modulus - remainder;
  }
  return chars.charAt(cd);
}

/// <summary>
/// モジュラス43
/// </summary>
/// <param name="barcode">バーコード</param>
/// <param name="modulus">モジュラス</param>
/// <returns>チェックデジット</returns>
function modulusNumber43(barcode, modulus) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%';
  let barcodes = Array.from(barcode);
  let sum = 0;
  for (let i = 0; i < barcodes.length; i++) {
    let d = chars.indexOf(barcodes[i].toUpperCase());
    sum += d;
  }
  let remainder = sum % modulus;
  let cd = chars.charAt(remainder);
  return cd;
}

</script>

引用文献

[メモ] 各種チェックデジットの計算方法 - Qiita
チェックデジットの計算方法桁数の多い数字を扱う場合、誤り検知用にチェックデジット(検証番号)といわれるものがあります。大抵は末尾についていたりします(末尾以外にある場合もあります)。いくつか計算…



コメント