isUserIdentify.mjs

import genPm from './genPm.mjs'
import isestr from './isestr.mjs'


/**
 * 判斷是否為有效中華民國身份證
 *
 * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/isUserIdentify.test.mjs Github}
 * @memberOf wsemi
 * @param {*} v 輸入任意資料
 * @returns {Promise} 回傳Promise,resolve為空代表有效,reject為錯誤訊息
 * @example
 * need test in browser
 *
 * isUserIdentify('A122471399')
 *     .then(function(){
 *         console.log('then')
 *         //code here
 *     })
 *
 */
function isUserIdentify(v) {

    let pm = genPm()

    //check
    if (!isestr(v)) {
        pm.reject('身份證字號非有效字串')
        return pm
    }

    //身分證字號長度
    if (v.length !== 10) {
        pm.reject('身份證字號長度非10位')
        return pm
    }

    //身分證字號格式,用正則表示式比對第一個字母是否為英文字母
    // if (isNaN(v.substr(1, 9)) || (!/^[A-Z]$/.test(v.substr(0, 1)))) {
    if (isNaN(v.substring(1, 1 + 9)) || (!/^[A-Z]$/.test(v.substring(0, 0 + 1)))) {
        pm.reject('身份證格式錯誤,字首需大寫英文')
        return pm
    }

    //按照轉換後權數的大小進行排序
    let idHeader = 'ABCDEFGHJKLMNPQRSTUVXYWZIO'

    //身分證字號轉換
    // v = (idHeader.indexOf(v.substring(0, 1)) + 10) + '' + v.substr(1, 9)
    v = (idHeader.indexOf(v.substring(0, 1)) + 10) + '' + v.substring(1, 1 + 9)

    //開始進行身分證數字的相乘與累加,依照順序乘上1987654321
    // let s = parseInt(v.substr(0, 1)) +
    //     parseInt(v.substr(1, 1)) * 9 +
    //     parseInt(v.substr(2, 1)) * 8 +
    //     parseInt(v.substr(3, 1)) * 7 +
    //     parseInt(v.substr(4, 1)) * 6 +
    //     parseInt(v.substr(5, 1)) * 5 +
    //     parseInt(v.substr(6, 1)) * 4 +
    //     parseInt(v.substr(7, 1)) * 3 +
    //     parseInt(v.substr(8, 1)) * 2 +
    //     parseInt(v.substr(9, 1))
    let s = parseInt(v.substring(0, 0 + 1)) +
            parseInt(v.substring(1, 1 + 1)) * 9 +
            parseInt(v.substring(2, 2 + 1)) * 8 +
            parseInt(v.substring(3, 3 + 1)) * 7 +
            parseInt(v.substring(4, 4 + 1)) * 6 +
            parseInt(v.substring(5, 5 + 1)) * 5 +
            parseInt(v.substring(6, 6 + 1)) * 4 +
            parseInt(v.substring(7, 7 + 1)) * 3 +
            parseInt(v.substring(8, 8 + 1)) * 2 +
            parseInt(v.substring(9, 9 + 1))

    //檢查碼
    // let checkNum = parseInt(v.substr(10, 1))
    let checkNum = parseInt(v.substring(10, 10 + 1))

    //模數-總和/模數(10)之餘數若等於第九碼的檢查碼則驗證成功, 若餘數為0檢查碼就是0
    if ((s % 10) === 0 || (10 - s % 10) === checkNum) {
        //有效
    }
    else {
        pm.reject('非有效身份證')
        return pm
    }

    pm.resolve()
    return pm
}


export default isUserIdentify