Frank Sun Blog on GitHub

身分證字號及統一編號驗證

2017-09-22

前言

  中華民國身分證字號及統一編號驗證,常常用到,規則不會變,所以可以直接當工具使用了,提供 C# 及 JavaScript 作法。

Csharp

身分證字號

/// <summary>
/// 驗身分證
/// </summary>
/// <param name="id">身分證字號</param>
/// <returns>身分字號是否符合格式</returns>
public static bool CheckIdCardNumber(string id)
{
    var format =  new Regex(@"^[A-Z]\d{9}$");
    if (!format.IsMatch(id)) return false;

    id = id.ToUpper();

    var a = new[]
    {
        10, 11, 12, 13, 14, 15, 16, 17, 34, 18, 19, 20, 21, 22, 35, 23, 24, 25, 26, 27, 28, 29, 32, 30, 31, 33
    };

    var b = new int[11];

    b[1] = a[(id[0]) - 65] % 10;

    var c = b[0] = a[(id[0]) - 65] / 10;

    for (var i = 1; i <= 9; i++)
    {
        b[i + 1] = id[i] - 48;
        c += b[i] * (10 - i);
    }

    return ((c % 10) + b[10]) % 10 == 0;
}

外籍居留證

/// <summary>
/// 外來人口統一證號驗證
/// </summary>
/// <param name="numberToCheck">要驗證的證號</param>
/// <returns>驗證結果</returns>
public static bool CheckForeignIdNumber(string numberToCheck)
{
    // 基礎檢查 「任意1個字母」+「A~D其中一個字母」+「8個數字」
    if (!Regex.IsMatch(numberToCheck, @"^[A-Za-z][A-Da-d]\d{8}$")) return false;
    numberToCheck = numberToCheck.ToUpper();

    // 縣市區域碼
    var cityCode = new[] { 10, 11, 12, 13, 14, 15, 16, 17, 34, 18, 19, 20, 21, 22, 35, 23, 24, 25, 26, 27, 28, 29, 32, 30, 31, 33 };
    // 計算時使用的容器,最後一個位置拿來放檢查碼,所以有11個位置(縣市區碼佔2個位置)
    var valueContainer = new int[11]; 
    valueContainer[0] = cityCode[numberToCheck[0] - 65] / 10; // 區域碼十位數
    valueContainer[1] = cityCode[numberToCheck[0] - 65] % 10; // 區域碼個位數
    valueContainer[2] = cityCode[numberToCheck[1] - 65] % 10; // 性別碼個位數
    // 證號執行特定數規則所產生的結果值的加總,這裡把初始值訂為區域碼的十位數數字(特定數為1,所以不用乘)
    var sumVal = valueContainer[0]; 

    // 迴圈執行特定數規則
    for (var i = 1; i <= 9; i++)
    {
        // 跳過性別碼,如果是一般身分證字號則不用跳過
        if (i > 1) 
        // 將當前證號於索引位置的數字放到容器的下一個索引的位置
            valueContainer[i + 1] = numberToCheck[i] - 48; 

        // 特定數為: 1987654321 ,因為首個數字1已經在sumVal初始值算過了,所以這裡從9開始
        sumVal += valueContainer[i] * (10 - i); 
    }

    // 此為「檢查碼 = 10 - 總和值的個位數數字 ; 若個位數為0則取0為檢查碼」的反推
    if ((sumVal + valueContainer[10]) % 10 == 0) return true; 
    return false;
}

統一編號

/// <summary>
/// 驗統編
/// </summary>
/// <param name="companyNumber">欲驗證的統編</param>
/// <returns>是否符合統編格式</returns>
public static bool CheckCompanyNumber(string companyNumber)
{
    // 假設統一編號為 A B C D E F G H
    // A - G 為編號, H 為檢查碼
    // A - G 個別乘上特定倍數, 若乘出來的值為二位數則將十位數和個位數相加
    // A x 1
    // B x 2
    // C x 1
    // D x 2
    // E x 1
    // F x 2
    // G x 4
    // H x 1
    // 最後將所有數值加總, 被 10 整除就為正確
    // 若上述演算不正確並且 G 為 7 得話, 再加上 1 被 10 整除也為正確
    if (companyNumber.Trim().Length != 8)
    {
        return false;
    }

    var monitor = new Regex(@"^[0-9]*$");

    if (!monitor.IsMatch(companyNumber)) return false;

    int[] intTmpVal = new int[6];
    int intTmpSum = 0;
    for (int i = 0; i < 6; i++)
    {
        // 位置在奇數位置的*2,偶數位置*1,位置計算從0開始
        if (i % 2 == 1)
            intTmpVal[i] = OverTen(int.Parse(companyNumber[i].ToString()) * 2);
        else
            intTmpVal[i] = OverTen(int.Parse(companyNumber[i].ToString()));

        intTmpSum += intTmpVal[i];
    }

    // 第6碼*4
    intTmpSum += OverTen(int.Parse(companyNumber[6].ToString()) * 4);

    // 第7碼*1
    intTmpSum += OverTen(int.Parse(companyNumber[7].ToString()));

    if (intTmpSum % 10 == 0) return true;
    if (int.Parse(companyNumber[6].ToString()) == 7 && (intTmpSum + 1) % 10 == 0) return true;

    return false;
}

JavaScript

身分證字號(含外籍居留證)

function IdCardNumberCheck(){
    var city = new Array(1, 10, 19, 28, 37, 46, 55, 64, 39, 73, 82, 2, 11, 20, 48, 29, 38, 47, 56, 65, 74, 83, 21, 3, 12, 30);
    id = id.toUpperCase();
    // 使用「正規表達式」檢驗格式
    if (!id.match(/^[A-Z]\d{9}$/) && !id.match(/^[A-Z][A-D]\d{8}$/)) {
        document.getElementById("PointMsg").innerHTML = "<span style='color:red; font-style:italic'>請輸入正確身分證字號格式</span>";
        document.getElementById("IdCardText").value = "";
    }
    else {
        var total = 0;
        if (id.match(/^[A-Z]\d{9}$/)) { //身分證字號
            //將字串分割為陣列(IE必需這麼做才不會出錯)
            id = id.split('');
            //計算總分
            total = city[id[0].charCodeAt(0) - 65];
            for (var i = 1; i <= 8; i++) {
                total += eval(id[i]) * (9 - i);
            }
        } else { // 外來人口統一證號
            //將字串分割為陣列(IE必需這麼做才不會出錯)
            id = id.split('');
            //計算總分
            total = city[id[0].charCodeAt(0) - 65];
            // 外來人口的第2碼為英文A-D(10~13),這裡把他轉為區碼並取個位數,之後就可以像一般身分證的計算方式一樣了。
            id[1] = id[1].charCodeAt(0) - 65;
            for (var i = 1; i <= 8; i++) {
                total += eval(id[i]) * (9 - i);
            }
        }
        //補上檢查碼(最後一碼)
        total += eval(id[9]);
        //檢查比對碼(餘數應為0);
        if (total % 10 == 0) {
            document.getElementById("PointMsg").innerHTML = "<span style='color:red; font-style:italic'></span>";
        }
        else {
            document.getElementById("PointMsg").innerHTML = "<span style='color:red; font-style:italic'>驗證錯誤,請輸入正確的身分證字號</span>";
            document.getElementById("IdCardText").value = "";
        }
    }
}

統一編號

function IdTaxNumberCheck(){
    var invalidList = "00000000,11111111";
    if (/^\d{8}$/.test(id) == false || invalidList.indexOf(id) != -1) {
        document.getElementById("PointMsg").innerHTML = "<span style='color:red; font-style:italic'>請輸入正確統一編號格式</span>";
        document.getElementById("IdTaxText").value = "";
    }

    var validateOperator = [1, 2, 1, 2, 1, 2, 4, 1],
        sum = 0,
        calculate = function (product) { // 個位數 + 十位數
            var ones = product % 10,
                tens = (product - ones) / 10;
            return ones + tens;
        };
    for (var i = 0; i < validateOperator.length; i++) {
        sum += calculate(id[i] * validateOperator[i]);
    }

    if (sum % 10 == 0 || (id[6] == "7" && (sum + 1) % 10 == 0)) {
        document.getElementById("PointMsg").innerHTML = "<span style='color:red; font-style:italic'></span>";
    } else {
        document.getElementById("PointMsg").innerHTML = "<span style='color:red; font-style:italic'>驗證失敗,請輸入正確統一編號格式</span>";
        document.getElementById("IdTaxText").value = "";
    }
} 

Similar Posts

Comments

Translator
Google AdSense
BloggerAds