R语言实现身份证号校验_24Sep2020

2020-09-24  本文已影响0人  liang_rujiang

目的:如题

规则:

校验码计算步骤

(1)十七位数字本体码加权求和公式
  S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
  Ai:表示第i位置上的身份证号码数字值(0~9)
  Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 (表示第i位置上的加权因子)
(2)计算模
  Y = mod(S, 11)

(3)根据模,查找得到对应的校验码
  Y: 0 1 2 3 4 5 6 7 8 9 10
  校验码: 1 0 X 9 8 7 6 5 4 3 2

实现:

library(tidyverse)
#mydata <- read.csv("HQMS_db_2020-09-22.csv", stringsAsFactors = FALSE) %>% as.tibble()
#save(mydata, file = "mydata.RData")
load("mydata.RData")
# id: remove space on two sides -------------------------------------------

rmspace <- function(x) map_chr(x, str_trim)
mydata$P13 <- rmspace(mydata$P13)

# id length ---------------------------------------------------------------

id_length <- mydata %>% 
    `$`("P13") %>%
    str_length
mydata$id_length <- id_length
table(mydata$id_length)

# id_legal ----------------------------------------------------------------

test <- mydata$P13[[18]]
test
mystr <- function(x) {
    out <- vector(length = 17)
    for (i in 1:17) {
        out[i] <- str_sub(x, i, i)
    }
    out
}
test
mystr(test)

id_chk <- function(x) {
    if (str_length(x) == 18) {
        weight <- c(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
        num <- as.numeric(mystr(x))
        temp <- weight * num
        y <- sum(temp) %% 11
        the18 <- str_sub(x, 18, 18)
        if (the18 %in% c("X", "x")) the18 <- 10 else the18 <- as.numeric(the18)
        chk <- switch(y + 1,
                      1,
                      0,
                      10,
                      9,
                      8,
                      7,
                      6,
                      5,
                      4,
                      3,
                      2
        )
        chk == the18
    }
    else {
        FALSE
    }
}

id_chk(test)
(test2 <- mydata$P13[1:20])
map_lgl(test2, id_chk)

mydata$id_legel <- mydata$P13 %>% map_lgl(id_chk)
上一篇下一篇

猜你喜欢

热点阅读