国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - PHP校驗15位和18位身份證號的類封裝

PHP校驗15位和18位身份證號的類封裝

2019-08-29 09:25mrr PHP教程

這篇文章主要介紹了PHP校驗15位和18位身份證號,需要的朋友可以參考下

新公司框架源碼的時候,發現了這個功能,于是搜索一番并封裝了一下身份證號校驗的類。

目前大家的身份證號大多是 18 位的,當然,也不排除有些老人的身份證號是 15 位的。

如果強制要求是 18 位的話,會比較好,因為 15 位的身份證號沒有校驗碼,可以說,只要了解大概結構,隨手都可以造出一系列身份證號碼來。

當然,如果只是單純的程序校驗, 18 位的身份證號碼也可以偽造,就是需要偽造者花點心思。

最好的還是調用相關部門給的接口,進行校驗。

本文所編寫的身份證號碼校驗,只是針對相關規則下的計算,是調用接口前能做的事情。

身份證號規則

15位:省份(2位) + 地級市(2位) + 縣級市(2位) + 出生年(2位) + 出生月(2位) + 出生日(2位) + 順序號(3位)

18位:省份(2位) + 地級市(2位) + 縣級市(2位) + 出生年(4位) + 出生月(2位) + 出生日(2位) + 順序號(3位) + 校驗位(1位)

相比之下, 18位 比 15位 多出生年 2位 、校驗位 1位 。

其中,順序號如果是偶數,則說明是女生,順序號是奇數,則說明是男生。

校驗位的計算:

有17位數字,分別是:

7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2

分別用身份證的前 17 位乘以上面相應位置的數字,然后相加。

接著用相加的和對 11 取模。

用獲得的值在下面 11 個字符里查找對應位置的字符,這個字符就是校驗位。

'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'

15位轉18位:

從上述的分析中,可以知道,只要補充上年分和校驗位就可以了。

一般情況下年份補充都是加上 19 就可以了。

校驗類的實現

通過分析身份證號的規則,了解到,有幾點是可以做的:

  • 檢查身份是否正確(一般不會變化,而且省份不多)
  • 檢查地級市和縣級市(如果有這方面的資源,可以考慮,不過一般不建議)
  • 檢查年月日
  • 檢查校驗碼

當然,因為可能部分人用的是 15位 的身份證號,所以需要一個轉換的方法,不過,這里還是建議限制需要 18位 的身份證號。

下面開始實現:

初始化:

class IDCardFilter
{
  /**
   * 身份證號碼校驗
   *
   * @param string $idCard
   * @return bool
   */
  public function vaild($idCard)
  {
    // 基礎的校驗,校驗身份證格式是否正確
    if (!$this->isCardNumber($idCard)) {
      return false;
    }

    // 將 15 位轉換成 18 位
    $idCard = $this->fifteen2Eighteen($idCard);

    // 檢查省是否存在
    if (!$this->checkProvince($idCard)) {
      return false;
    }

    // 檢查生日是否正確
    if (!$this->checkBirthday($idCard)) {
      return false;
    }

    // 檢查校驗碼
    return $this->checkCode($idCard);
  }
}

上面已經實現了一個校驗的方法,里面調用了類里的很多方法,下面一一實現。

檢測是否是身份證號碼:

這一塊的處理比較簡單,一個正則表達式搞定了。

其中, (^\d{15}$) 用于匹配 15位 身份證號的情況; (^\d{17}(\d|X)$) 用于匹配 18位 身份證號的情況。

const REGX = '#(^\d{15}$)|(^\d{17}(\d|X)$)#';

/**
 * 檢測是否是身份證號碼
 *
 * @param string $idCard
 * @return boolean
 */
public function isCardNumber($idCard)
{
  return preg_match(self::REGX, $idCard);
}

15位轉18位:

邏輯不復雜,先判斷是否是15位,然后判斷需要添加的年份,最終生成校驗碼拼接返回就OK了。

/**
 * 15位轉18位
 *
 * @param string $idCard
 * @return void
 */
public function fifteen2Eighteen($idCard)
{
  if (strlen($idCard) != 15) {
    return $idCard;
  }

  // 如果身份證順序碼是996 997 998 999,這些是為百歲以上老人的特殊編碼
  // $code = array_search(substr($idCard, 12, 3), [996, 997, 998, 999]) !== false ? '18' : '19';
  // 一般 19 就夠了
  $code = '19';
  $idCardBase = substr($idCard, 0, 6) . $code . substr($idCard, 6, 9);
  return $idCardBase . $this->genCode($idCardBase);
}

校驗碼的生成:

詳細計算規則見上面,這里就不做重復的闡述了。

/**
 * 生成校驗碼
 *
 * @param string $idCardBase
 * @return void
 */
final protected function genCode($idCardBase)
{
  $idCardLength = strlen($idCardBase);
  if ($idCardLength != 17) {
    return false;
  }
  $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  $verifyNumbers = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
  $sum = 0;
  for ($i = 0; $i < $idCardLength; $i++) {
    $sum += substr($idCardBase, $i, 1) * $factor[$i];
  }
  $index = $sum % 11;
  return $verifyNumbers[$index];
}

檢查省份是否正確:

protected $provinces = [
  11 => "北京", 12 => "天津", 13 => "河北",  14 => "山西", 15 => "內蒙古",
  21 => "遼寧", 22 => "吉林", 23 => "黑龍江", 31 => "上海", 32 => "江蘇",
  33 => "浙江", 34 => "安徽", 35 => "福建",  36 => "江西", 37 => "山東", 41 => "河南",
  42 => "湖北", 43 => "湖南", 44 => "廣東",  45 => "廣西", 46 => "海南", 50 => "重慶",
  51 => "四川", 52 => "貴州", 53 => "云南",  54 => "西藏", 61 => "陜西", 62 => "甘肅",
  63 => "青海", 64 => "寧夏", 65 => "新疆",  71 => "臺灣", 81 => "香港", 82 => "澳門", 91 => "國外"
];

/**
 * 檢查省份是否正確
 *
 * @param string $idCard
 * @return void
 */
public function checkProvince($idCard)
{
  $provinceNumber = substr($idCard, 0, 2);
  return isset($this->provinces[$provinceNumber]);
}

檢測生日是否正確:

這里也是用正則匹配,匹配出年月日的。

/**
 * 檢測生日是否正確
 *
 * @param string $idCard
 * @return void
 */
public function checkBirthday($idCard)
{
  $regx = '#^\d{6}(\d{4})(\d{2})(\d{2})\d{3}[0-9X]$#';
  if (!preg_match($regx, $idCard, $matches)) {
    return false;
  }
  array_shift($matches);
  list($year, $month, $day) = $matches;
  return checkdate($month, $day, $year);
}

校驗碼比對:

話說, 15位 轉 18位 的都完全不用考慮這個方法了。

/**
 * 校驗碼比對
 *
 * @param string $idCard
 * @return void
 */
public function checkCode($idCard)
{
  $idCardBase = substr($idCard, 0, 17);
  $code = $this->genCode($idCardBase);
  return $idCard == ($idCardBase . $code);
}

完整代碼

傳送門:IDCardFilter

最后

這個功能最多算是新穎吧,畢竟之前沒有接觸過。很開心代碼片段里又增加了新的成員。

以上所述是小編給大家介紹的PHP校驗15位和18位身份證號的類封裝,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 一区自拍 | www.国产区 | 欧美日韩一级电影 | 精品国产精品三级精品av网址 | 在线视频一区二区 | 交视频在线观看国产 | 国产午夜在线 | 婷婷五综合 | 少妇精品久久久久久久久久 | 欧美精品一区二区三区在线四季 | 欧美精品国产精品 | 精品久久久久久久久久久久 | 国产亚洲一区二区三区 | 亚洲精选久久 | 久草成人网 | 激情总合网 | 国产精品久久久亚洲 | 日韩经典一区 | 久久精品日产第一区二区三区 | 国内精品久久久久久中文字幕 | 91嫩草国产露脸精品国产 | 久久久久一区 | 欧美日韩国产在线观看 | 欧美日韩免费在线 | 国产在线色 | 色天堂影院 | av免费网| 日韩一二三区视频 | 这里只有精品在线视频观看 | 九色网址 | 亚洲欧美日韩精品久久亚洲区 | 久久99精品久久久久久国产越南 | 欧美影 | 亚洲精品区 | 欧美free性丝袜xxxxhd | 在线观看免费av网 | 欧美中文在线 | 国产在线网站 | 成人综合电影网 | 成人av网站在线观看 | 婷婷精品|