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)