15 桁から 18 桁の ID 番号への変換を実現し、中国本土住民 ID カード、香港住民 ID カード、マカオ ID カード、台湾 ID カードを検証します。
- /**
- * ID カード ツール カテゴリ
- *
- * @author Tongle Xu 2013-6-6
- * @copyright Copyright (c) 2003-2103 tinysoft.com
- * @license http://www .tintsoft.com
- * @version $Id$
- */
- class Utils_Idcard {
- /**
- * 中国国民 ID 番号の最小の長さ。
- */
- const CHINA_ID_MIN_LENGTH = 15;
- /**
- * 中国国民 ID 番号の最大長。
- */
- const CHINA_ID_MAX_LENGTH = 18;
- /**
- * 最低年数
- */
- const MIN = 1930;
- /**
- *都道府県および市区町村コード表
- */
- public static $cityCode = array ("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" );
- /**
- * ビットあたりの重み付け係数
- */
- public static $power =配列 (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 );
- /**
- * チェックコードの18桁目
- */
- public static $verifyCode = array ("1","0","X","9","8","7","6","5","4","3","2" );
- /**
- *国内身分証明書の確認
- */
- public static $cityCodes = array ('11' => '北京' );
-
- /**
- * 15桁のID番号を18桁に変換します
- *
- * @param idCard 15桁のIDコード
- * @return 18桁のIDコード
- */
- public static function conver15CardTo18($idCard) {
- $ idCard18 = "";
- if (strlen ( $idCard ) != self::CHINA_ID_MIN_LENGTH) {
- return null;
- }
- if (self::isNum ( $idCard )) {
- // 获取警戒
- $ s年 = '19' 。 substr ( $idCard, 6, 2 );
- $idCard18 = substr ( $idCard, 0, 6 ) 。 $s年 。 substr ( $idCard, 8 );
- // 转换字符数组
- $iArr = str_split ( $idCard18 );
- if ($iArr != null) {
- $iSum17 = self::getPowerSum ( $iArr );
- //获取校验位
- $sVal = self::getCheckCode18 ( $iSum17 );
- if (strlen ( $sVal ) > 0) {
- $idCard18 .= $sVal;
- } else {
- return null;
- }
- }
- } else {
- return null;
- }
- return $idCard18;
- }
-
- /**
- * IDカードが合法かどうかを確認してください
- */
- public static function validateCard($idCard) {
- $card = trim ( $idCard );
- if ( self::validateIdCard18 ( $card )) {
- return true;
- }
- if (self::validateIdCard15 ( $card )) {
- return true;
- }
- return false;
- }
-
- /**
- * 18 桁の ID コードが合法かどうかを確認します
- *
- * @param int $idCard ID コード
- * @return boolean 合法かどうかを確認します
- * /
- public static function validateIdCard18($idCard) {
- $bTrue = false;
- if (strlen ( $idCard ) == self::CHINA_ID_MAX_LENGTH) {
- // 前17位
- $code17 = substr ( $idCard, 0, 17 );
- // 第18位
- $code18 = substr ( $idCard, 17, 1 );
- if (self::isNum ( $code17 )) {
- $iArr = str_split ( $code17 );
- if ($ iArr != null) {
- $iSum17 = self::getPowerSum ( $iArr );
- // 获取校验位
- $val = self::getCheckCode18 ( $iSum17 );
- if (strlen ( $val ) > 0 && $val == $code18) {
- $bTrue = true;
- }
- }
- }
- }
- return $bTrue;
- }
-
- /**
- * 15 桁の ID コードが合法かどうかを確認します
- *
- * @param string $idCard ID コード
- * @return boolean 合法かどうかを確認します
- */
- public static function validateIdCard15($idCard) {
- if (strlen ( $idCard ) != self::CHINA_ID_MIN_LENGTH) {
- return false;
- }
- if (self::isNum ( $idCard )) {
- $proCode = substr ( $idCard, 0, 2 );
- if (! isset ( self::$cityCodes [$proCode] )) {
- return false;
- }
- //升到達18位
- $idCard = self::conver15CardTo18($idCard);
- return self::validateIdCard18 ($idCard);
- } else {
- return false;
- }
- return true;
- }
-
- /**
- * ID 番号に基づいて年齢を取得します
- *
- * @param string idCard ID 番号
- * @return age
- */
- public static function getAgeByIdCard($idCard) {
- $iAge = 0;
- if ( strlen ( $idCard ) == self::CHINA_ID_MIN_LENGTH) {
- $idCard = self::conver15CardTo18 ( $idCard );
- }
- $year = substr ( $idCard, 6, 4 );
- $iCurr Year = date ( 'Y ', time () );
- $iAge = $iCurr Year - $year;
- return $iAge;
- }
-
- /**
- * ID 番号に基づいて誕生日を取得します
- *
- * @param string $idCard ID 番号
- * @return NULL string
- */
- public static function getDateByIdCard($idCard) {
- $len = strlen ( $idCard );
- if ($len < self::CHINA_ID_MIN_LENGTH) {
- return null;
- } else if ($len == CHINA_ID_MIN_LENGTH) {
- $idCard = self::conver15CardTo18 ( $idCard );
- }
- return substr ( $idCard, 12, 2 );
- }
- /**
- * ID 番号に基づいて性別を取得します
- *
- * @param string $idCard ID 番号
- * @return 性別 (M-男性、F-女性、N-不明)
- */
- public static function getGenderByIdCard($idCard) {
- $sGender = "N";
- if (strlen ( $idCard ) == self::CHINA_ID_MIN_LENGTH) {
- $idCard = self: :conver15CardTo18 ( $idCard );
- }
- $sCardNum = substr ( $idCard, 16, 1 );
- if (( int ) $sCardNum % 2 != 0) {
- $sGender = "M";
- } else {
- $sGender = "F";
- }
- return $sGender;
- }
- /**
- * ID 番号に基づいて戸籍の都道府県を取得します
- *
- * @param string $idCard ID 番号
- * @return string
- */
- public static function getProvinceByIdCard($idCard) {
- $len = strlen ( $idCard );
- $sProvince = null;
- $sProvinNum = "";
- if ($len == self::CHINA_ID_MIN_LENGTH || $len == self::CHINA_ID_MAX_LENGTH) {
- $sProvinNum = substr ( $idCard, 0, 2 );
- }
- $sProvince = self::$cityCodes [$sProvinNum];
- return $sProvince;
- }
- /**
- *番号認証
- *
- * @param int $val
- */
- public static function isNum($val) {
- return $val == null || $val == "" ? false : 0 <; preg_match ( '/^[0-9]*$/', $val );
- }
- /**
- * 現在の日付より小さい日付が有効かどうかを検証します
- *
- * @param int $iyear 検証する日付 (年)
- * @param int $iMonth 検証する日付 (月 1 ~ 12)
- * @param int $iDate 検証する日付 (日)
- * @return 有効ですか
- */
- public static function valiDate($i Year, $iMonth, $iDate) {
- $year = date ( 'Y', time () );
- if ($iyear < self::MIN || $i Year >= $year) {
- return false;
- }
- if ($iMonth < 1 || $iMonth > 12) {
- return false;
- }
- switch ($iMonth) {
- ケース 4 :
- ケース 6 :
- ケース 9 :
- ケース 11 :
- $datePerMonth = 30;
- ブレーク;
- ケース 2 :
- $dm = (($i年 % 4 == 0 && $i年 % 100 != 0) || ($i年 % 400 == 0)) && ($i年 > self::MIN && $i年 < $年);
- $datePerMonth = $dm ? 29 : 28;
- ブレーク;
- デフォルト :
- $datePerMonth = 31;
- }
- return ($iDate >= 1) && ($iDate }
-
- /**
- * IDカードの各ビットと対応するビットの重み係数を乗算した後、合計値が得られます
- *
- * @param array $iArr
- * @return ID code.
- * /
- プライベート静的関数 getPowerSum($iArr) {
- $iSum = 0;
- $power_len = count ( self::$power );
- $iarr_len = count ( $iArr );
- if ($power_len == $iarr_len) {
- for($i = 0; $i for($j = 0; $j if ($i == $j) {
- $iSum = $iSum + $iArr [$i] * self::$power [$j];
- }
- }
- }
- }
- return $iSum;
- }
-
- /**
- * 累乗和の11を法とした値を求め、チェックデジット判定用の余りを求めます
- *
- * @param int $iSum
- * @return check digit
- */
- プライベート静的関数 getCheckCode18($iSum) {
- $sCode = "";
- switch ($iSum % 11) {
- case 10 :
- $sCode = "2";
- Break;
- case 9 :
- $ sCode = "3";
- ブレーク;
- ケース 8 :
- $sCode = "4";
- ブレーク;
- ケース 7 :
- $sCode = "5";
- ブレーク;
- ケース 6 :
- $sCode = "6" ;
- ブレーク;
- ケース 5 :
- $sCode = "7";
- ブレーク;
- ケース 4 :
- $sCode = "8";
- ブレーク;
- ケース 3 :
- $sCode = "9";
- ブレーク;
- ケース 2 :
- $sCode = "x";
- ブレーク;
- ケース 1 :
- $sCode = "0";
- ブレーク;
- ケース 0 :
- $sCode = "1";
- ブレーク;
- }
- return $sCode ;
- }
- }
复制代
- /**
- * ID カード ツール カテゴリ
- *
- * @author Tongle Xu 2013-6-6
- * @copyright Copyright (c) 2003-2103 tinysoft.com
- * @license http://www .tintsoft.com
- * @version $Id$
- */
- class Utils_Idcard {
- /**
- * 中国国民 ID 番号の最小の長さ。
- */
- const CHINA_ID_MIN_LENGTH = 15;
- /**
- * 中国国民 ID 番号の最大長。
- */
- const CHINA_ID_MAX_LENGTH = 18;
- /**
- * 最低年数
- */
- const MIN = 1930;
- /**
- *都道府県および市区町村コード表
- */
- public static $cityCode = array ("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" );
- /**
- * ビットあたりの重み付け係数
- */
- public static $power =配列 (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 );
- /**
- * チェックコードの18桁目
- */
- public static $verifyCode = array ("1","0","X","9","8","7","6","5","4","3","2" );
- /**
- *国内身分証明書の確認
- */
- public static $cityCodes = array ('11' => '北京','12' => '天津','13' => '河北','14' => '山西','15' => '内モンゴル','22' => '吉林','23' => ' => '上海','32' => '浙江','34' => '福建' ' => '江西','37' => '河南','42' => '湖南','44 ' => '広東','45' => '46' => '重慶','51' => 52 ' => '貴州'、'53' => 'チベット'、'62' => ' 15 ' => '内モンゴル'、'21' => '吉林'、'23' => '上海'、 '32' => '江蘇'、'33' => '安徽'、'35' => '江西'、 '37' => '山東'、'41' => '湖北'、'43' => '広東' 、' 45' => '広西'、' 46' => '重慶'、' 51' => '貴州' 、' 53' => '雲南'、' 54' => '陝西省'、' 63' => 、' 64' => '寧夏'、' 65' => '台湾'、' 82' => ',' 91' => '海外','63' => '寧夏','71' => ',' 81' => '香港',
- '82' => 'マカオ','91' => '海外' );
-
- /**
- *台湾 ID カード認証
- *
- * @var array
- */
- public static $twFirstCode = 配列 (' A' => 10,'B' => 11,'C' => 12,'D' => 13,'E' => 14,'F' => 15 、'G' => 16、'H' => 18、'L' => 21、' N' => 22、'P' => 24、'S' => 27、'U' => 28、'V' => 30、'W' => 33、'I' => ; 34,' O' => 35 );
-
- /**
- * 香港のIDカード認証
- */
- public static $hkFirstCode = array ('A' => 1,'B' => 2,'C' = > 3、'R' => 21、'X' => 23、'O' => 15,'N ' => 14 );
-
- /**
- * 15桁のID番号を18桁に変換します
- *
- * @param idCard 15桁のIDコード
- * @return 18桁のIDコード
- */
- public static function conver15CardTo18($idCard) {
- $idCard18 = "";
- if (strlen ( $idCard ) != self: :CHINA_ID_MIN_LENGTH) {
- return null;
- }
- if (self::isNum ( $idCard )) {
- // 生まれた年、月、日を取得します
- $s Year = '19' . substr ( $idCard, 6, 2 );
- $idCard18 = substr ( $idCard, 0, 6 ) . $s Year . substr ( $idCard, 8 );
- // 文字配列を変換します
- $iArr = str_split ( $idCard18 );
- if ($iArr ! = null) {
- $iSum17 = self::getPowerSum ( $iArr );
- // チェックデジットを取得します
- $sVal = self::getCheckCode18 ( $iSum17 );
- if (strlen ( $sVal ) > 0) {
- $idCard18 .= $sVal;
- } else {
- return null;
- }
- }
- } else {
- return null;
- }
- return $idCard18;
- }
-
- /**
- * IDカードが合法かどうかを確認してください
- */
- public static function validateCard($idCard) {
- $card = trim ( $idCard );
- if (self::validateIdCard18 ( $card )) {
- return true;
- }
- if (self::validateIdCard15 ( $card )) {
- return true;
- }
- $cardval = self::validateIdCard10 ( $card );
- if ($cardval != null) {
- if ($cardval [2] == "true") {
- return true;
- }
- }
- false を返します;
- }
-
- /**
- * 18 桁の ID コードが合法かどうかを確認します
- *
- * @param int $idCard ID コード
- * @return boolean 合法かどうかを確認します
- */
- public static function validateIdCard18($idCard) {
- $bTrue = false;
- if (strlen ( $idCard ) == self::CHINA_ID_MAX_LENGTH) {
- // 前17位
- $ code17 = substr ( $idCard, 0, 17 );
- // 第18位
- $code18 = substr ( $idCard, 17, 1 );
- if (self::isNum ( $code17 )) {
- $iArr = str_split ( $code17 );
- if ($iArr != null) {
- $iSum17 = self::getPowerSum ( $iArr );
- // 获取校验位
- $val = self::getCheckCode18 ( $iSum17 );
- if (strlen ( $val ) > 0 && $val == $code18) {
- $bTrue = true;
- }
- }
- }
- }
- return $bTrue;
- }
-
- /**
- * 15 桁の ID コードが合法かどうかを確認します
- *
- * @param string $idCard ID コード
- * @return boolean 合法かどうかを確認します
- */
- public static function validateIdCard15($idCard) {
- if (strlen ( $idCard ) != self::CHINA_ID_MIN_LENGTH) {
- return false;
- }
- if (self::isNum ( $idCard )) {
- $proCode = substr ( $idCard, 0, 2 );
- if (! isset ( self::$cityCodes [$proCode] )) {
- return false;
- }
- // 升到達18位
- $idCard = self::conver15CardTo18 ( $idCard );
- return self::validateIdCard18 ( $idCard );
- } else {
- return false;
- }
- return true;
- }
-
- /**
- * 10 桁の ID コードが合法かどうかを確認してください
- *
- * @param idCard ID コード
- * @return ID カード情報配列
- * [0] - 台湾、マカオ、香港 [1] - 性別 (男性 M、女性 F、不明 N) [2] - 合法か (合法的 true、合法的 false ではない)
- * ID 番号でない場合は、null を返します
- *
- */
- public static function validateIdCard10($idCard) {
- $info = array ();
- $card = str_replace ( "[\(|\)]", "", $card );
- $len = strlen ( $card );
- if ($len != 8 && $ len != 9 && $len != 10) {
- return null;
- }
- if (0 $info [0] = "台湾";
- $char2 = substr ( $ idCard, 1, 1 );
- if ($char2 == "1") {
- $info [1] = "M";
- } else if ($char2 == "2") {
- $info [1] = "F";
- } else {
- $info [1] = "N";
- $info [2] = "false";
- return $info;
- }
- $info [2] = self::validateTWCard ( $idCard )? "true" : "false";
- } else if (0 $info [0] = "澳门";
- $info [1] = "N";
- // TODO
- } else if (0 $info [0] = "香港";
- $info [1] = "N";
- $info [2] = self::validateHKCard ( $idCard ) ? "true" : "false";
- } else {
- return null;
- }
- return info;
- }
- /**
- * 台湾 ID カード番号を確認します
- *
- * @param string idCard ID カード番号
- * @return 確認コードが一致しています
- */
- public static function validateTWCard($idCard) {
- $start = substr ( $idCard, 0, 1 );
- $mid = substr ( $idCard, 1, 8 );
- $end = substr ( $idCard, 9, 1 );
- $iStart = self::$twFirstCode ['start'] ;
- $sum = $iStart / 10 + ($iStart % 10) * 9;
- $chars = str_split ( $mid );
- $iflag = 8;
- foreach ( $chars as $c ) {
- $sum = $ sum + $c + "" * $iflag;
- $iflag --;
- }
- return ($sum % 10 == 0 ? 0 : (10 - $sum % 10)) == $end ? true : false;
- }
- /**
- * 香港 ID カード番号を確認します (バグがあり、一部の特殊な ID カードは確認できません)
- *
- * ID カードの最初の 2 桁は英語です。英語の文字が 1 文字だけ表示されている場合は、それが英語です。最初の数字がスペースであることを意味し、数字の 58 に対応し、最初の 2 つの英語の文字 A ~ Z はそれぞれ 10 ~ 35 の数字に対応します
- * チェック コードの最後の数字は、0 ~ 9 に文字「A」、「A」を加えたものです。 " は 10 を表します
- *
- *
* @return 認証コードが一致するかどうか
- */
- public static function validateHKCard($idCard) {
- $card = str_replace ( "[\(|\)]", "", $card );
- $sum = 0;
- if (strlen ( $card ) == 9) {
- $card0_arr = str_split ( strtoupper ( substr ( $card, 0, 1 ) ) );
- $card1_arr = str_split ( strtoupper ( substr ( $card , 1, 1 ) ) );
- $sum = ($card0_arr [0] - 55) * 9 。 ($card1_arr [0] - 55) * 8;
- $card = substr ( $card, 1, 8 );
- } else {
- $card0_arr = str_split ( strtoupper ( substr ( $card, 0, 1 ) ) );
- $sum = 522 + ($card0_arr [0] - 55) * 8;
- }
- $mid = substr ( $card, 1, 6 );
- $end = substr ( $card, 7, 1 );
- $chars = str_split ( $mid );
- $iflag = 7;
- foreach ( $chars as $c ) {
- $sum = $sum + $c + "" * $iflag;
- $iflag --;
- }
- if (strtoupper ( $end ) == "A") {
- $sum = $sum + 10;
- } else {
- $sum = $sum + $end;
- }
- return ($sum % 11 == 0) ? true : false;
- }
- /**
- * ID 番号に基づいて年齢を取得します
- *
- * @param string idCard ID 番号
- * @return age
- */
- public static function getAgeByIdCard($idCard) {
- $iAge = 0;
- if (strlen ( $idCard ) == self::CHINA_ID_MIN_LENGTH) {
- $ idCard = self::conver15CardTo18 ( $idCard );
- }
- $year = substr ( $idCard, 6, 4 );
- $iCurr Year = date ( 'Y', time () );
- $iAge = $iCurryear - $ year;
- return $iAge;
- }
- /**
- * ID 番号に基づいて誕生日を取得します
- *
- * @param string $idCard ID 番号
- * @return NULL string
- */
- public static function getDateByIdCard($idCard) {
- $len = strlen ( $idCard );
- if ($len < self::CHINA_ID_MIN_LENGTH ) {
- return null;
- } else if ($len == CHINA_ID_MIN_LENGTH) {
- $idCard = self::conver15CardTo18 ( $idCard );
- }
- return substr ( $idCard, 12, 2 );
- }
- / **
- * ID 番号に基づいて性別を取得します
- *
- * @param string $idCard ID 番号
- * @return 性別 (M-男性、F-女性、N-不明)
- */
- public static function getGenderByIdCard($idCard) {
- $sGender = "N";
- if (strlen ( $idCard ) == self::CHINA_ID_MIN_LENGTH) {
- $idCard = self::conver15CardTo18 ( $idCard );
- }
- $sCardNum = substr ( $idCard, 16, 1 );
- if (( int ) $sCardNum % 2 != 0) {
- $sGender = "M";
- } else {
- $sGender = "F";
- }
- return $sGender;
- }
- /**
- * ID 番号に基づいて戸籍の都道府県を取得します
- *
- * @param string $idCard ID 番号
- * @return string
- */
- public static function getProvinceByIdCard($idCard) {
- $len = strlen ( $idCard );
- $sProvince = null;
- $sProvinNum = "";
- if ($len == self::CHINA_ID_MIN_LENGTH || $len == self::CHINA_ID_MAX_LENGTH) {
- $sProvinNum = substr ( $idCard, 0, 2 );
- }
- $sProvince = self::$cityCodes [$sProvinNum];
- return $sProvince;
- }
- / **
- *番号認証
- *
- * @param int $val
- */
- public static function isNum($val) {
- return $val == null || $val == "" ? false : 0 <; preg_match ( '/^[0-9]*$/', $val );
- }
- /**
- * 現在の日付より小さい日付が有効かどうかを検証します
- *
- * @param int $iyear 検証する日付 (年)
- * @param int $iMonth 検証する日付 (月 1 ~ 12)
- * @param int $iDate 検証する日付 (日)
- * @return 有効ですか
- */
- public static function valiDate($i Year, $iMonth, $iDate) {
- $year = date ( 'Y', time () );
- if ($iyear < self::MIN || $i Year >= $year) {
- return false;
- }
- if ($iMonth < 1 || $iMonth > 12) {
- return false;
- }
- switch ($iMonth) {
- ケース 4 :
- ケース 6 :
- ケース 9 :
- ケース 11 :
- $datePerMonth = 30;
- ブレーク;
- ケース 2 :
- $dm = (($i年 % 4 == 0 && $i年 % 100 != 0) || ($i年 % 400 == 0)) && ($i年 > self::MIN && $i年 < $年);
- $datePerMonth = $dm ? 29 : 28;
- break;
- default:
- $datePerMonth = 31;
- }
- return ($iDate >= 1) && ($iDate }
- /**
- * 将身份承認された各ビットと対のビットの追加係数の後に、値
- *
- * @param array $iArr
- * @return 自身のコードが再び得られます。
- */
- プライベート静的関数 getPowerSum($iArr) {
- $iSum = 0;
- $power_len = count ( self::$power );
- $iarr_len = count ( $iArr );
- if ($power_len == $ iarr_len) {
- for($i = 0; $i < $iarr_len; $i ++) {
- for($j = 0; $j < $power_len; $j ++) {
- if ($i == $j) {
- $iSum = $iSum + $iArr [$i] * self::$power [$j];
- }
- }
- }
- }
- return $iSum;
- }
- /**
- * 累乗和の11を法とした値を求め、チェックデジット判定用の余りを求めます
- *
- * @param int $iSum
- * @return check digit
- */
- プライベート静的関数 getCheckCode18($iSum) {
- $sCode = "";
- switch ($iSum % 11) {
- case 10 :
- $sCode = "2";
- Break;
- case 9 :
- $sCode = "3";
- ブレーク;
- ケース 8 :
- $sCode = "4";
- ブレーク;
- ケース 7 :
- $sCode = "5";
- ブレーク;
- ケース 6 :
- $sCode = " 6";
- ブレーク;
- ケース 5 :
- $sCode = "7";
- ブレーク;
- ケース 4 :
- $sCode = "8";
- ブレーク;
- ケース 3 :
- $sCode = "9";
- ブレーク;
- ケース 2 :
- $sCode = "x";
- ブレーク;
- ケース 1 :
- $sCode = "0";
- ブレーク;
- ケース 0 :
- $sCode = "1";
- ブレーク;
- }
- return $sCode;
- }
- }
复制代
|