php身份证校验

  1. <?php
  2. /*
  3. * 校验规则是:
  4. * (1)十七位数字本体码加权求和公式
  5. * S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
  6. * Ai:表示第i位置上的身份证号码数字值
  7. * Wi:表示第i位置上的加权因子
  8. * Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
  9. * (2)计算模
  10. * Y = mod(S, 11)
  11. * (3)通过模得到对应的校验码
  12. * Y: 0 1 2 3 4 5 6 7 8 9 10
  13. * 校验码: 1 0 X 9 8 7 6 5 4 3 2
  14. * 也就是说,如果得到余数为1则最后的校验位p应该为对应的0.如果校验位不是,则该身份证号码不正确。
  15. * */
  16. class cardCheack{
  17. static private $powers = array('7','9','10','5','8','4','2','1','6','3','7','9','10','5','8','4','2'); #17
  18. static private $parityBit = array('1','0','X','9','8','7','6','5','4','3','2');
  19. static public function validId($cardno='')
  20. {
  21. $ret = array('isvalid'=>'', 'msg'=>'');
  22. if(empty($cardno)){
  23. return $ret;
  24. }
  25. switch(strlen($cardno)){
  26. case 15:
  27. $ret= self::validId15($cardno); break;
  28. case 18:
  29. $ret= self::validId18($cardno); break;
  30. default:
  31. return array(
  32. 'isvalid'=>false,
  33. 'msg'=>'',
  34. );
  35. }
  36. return $ret;
  37. }
  38. #18bit身份证号校验
  39. #@param: cardno 身份证号
  40. #@return: true, false
  41. static public function validId18($cardno='')
  42. {
  43. $_ret = array();
  44. $_cardno = $cardno.'';
  45. $_num = substr($cardno, 0, 17);
  46. $_parityBit = (int)substr($cardno, 17);
  47. $_powers = 0;
  48. for($i = 0; $i < 17; $i++){
  49. if($_num[$i] < '0' || $_num[$i] > '9'){
  50. return array(
  51. 'isvalid'=>false,
  52. 'msg'=>'',
  53. );
  54. break;
  55. }else{
  56. #加权
  57. $_powers += intval($_num[$i])*intval(self::$powers[$i]);
  58. #性别
  59. if($i==16 && intval($_num[$i])%2==0){
  60. $_ret['msg'] = 'female';
  61. }else{
  62. $_ret['msg'] = 'male';
  63. }
  64. }
  65. }
  66. #校验
  67. $mod = intval($_powers)%11;
  68. $_ret['isvalid'] = (strtoupper(self::$parityBit[$mod])==$_parityBit) ? true: false;
  69. return $_ret;
  70. }
  71. #15bit身份证号校验
  72. #@param: cardno 身份证号
  73. #@return: true, false
  74. public function validId15($cardno=''){
  75. $cardno = $cardno.'';
  76. $len = strlen($cardno);
  77. for($i=0; $i<$len; $i++){
  78. if($cardno[$i] < '0' || $carno[$i] > '9'){
  79. return array(
  80. 'isvalid'=>false,
  81. 'msg'=>'',
  82. );
  83. break;
  84. }
  85. }
  86. $_year = substr($cardno, 6, 2);
  87. $_month = substr($cardno, 8, 2);
  88. $_day = substr($cardno, 10, 2);
  89. $_sexbit= substr($cardno, 14);
  90. #校验年份
  91. if($_year < '01' || $_year > '90'){
  92. return array(
  93. 'isvalid'=>false,
  94. 'msg'=>'',
  95. );
  96. }
  97. if($_month < '01' || $_month > '12'){
  98. return array(
  99. 'isvalid'=>false,
  100. 'msg'=>'',
  101. );
  102. }
  103. if($_day < '01' || $_day> '31') {
  104. return array(
  105. 'isvalid'=>false,
  106. 'msg'=>'',
  107. );
  108. }
  109. #设置性别
  110. return array(
  111. 'isvalid'=>true,
  112. 'msg'=>!!$_sexbit%2? 'male': 'felmale',
  113. );
  114. }
  115. }
  116. /*$obj = new cardCheack();
  117. var_dump($obj->validId('412728198610110071'));
  118. */
  119. var_dump(cardCheack::validId('412728198610110071'));





posted @ 2015-07-23 09:44  laughingLau  阅读(427)  评论(0编辑  收藏  举报