|
1 | 1 | #' @title Finnish Personal Identification Number Control Character Calculator
|
2 |
| -#' @description Calculate a valid control character for an incomplete |
| 2 | +#' @description Calculate a valid control character for an incomplete |
3 | 3 | #' Finnish personal identification numbers (hetu).
|
4 | 4 | #' @param pin An incomplete PIN that ONLY has a date, century marker (optional,
|
5 | 5 | #' see parameter with.century) and personal number
|
6 |
| -#' @param with.century If TRUE (default), the function assumes that the PIN |
7 |
| -#' input contains a century marker (DDMMYYQZZZ). If FALSE, the function |
| 6 | +#' @param with.century If TRUE (default), the function assumes that the PIN |
| 7 | +#' input contains a century marker (DDMMYYQZZZ). If FALSE, the function |
8 | 8 | #' assumes that the PIN contains only date and personal number (DDMMYYZZZ).
|
9 | 9 | #' @details This method of calculating the control character was devised by
|
10 |
| -#' mathematician Erkki Pale (1962) to detect input errors but also to |
11 |
| -#' detect errors produced by early punch card machines. The long number |
| 10 | +#' mathematician Erkki Pale (1962) to detect input errors but also to |
| 11 | +#' detect errors produced by early punch card machines. The long number |
12 | 12 | #' produced by writing the birth date and the personal number together are
|
13 | 13 | #' divided by 31 and the remainder is used to look up the control character
|
14 | 14 | #' from a separate table containing alphanumeric characters except letters
|
15 | 15 | #' G, I, O, Q and Z.
|
16 |
| -#' |
17 |
| -#' The method of calculating the control character does not need century |
| 16 | +#' |
| 17 | +#' The method of calculating the control character does not need century |
18 | 18 | #' character and therefore the function has an option to omit it.
|
19 | 19 | #' @return Control character, either a number 0-9 or a letter.
|
20 | 20 | #' @author Pyry Kantanen
|
|
25 | 25 | #' hetu_control_char("010101010", with.century = FALSE)
|
26 | 26 | #' @export
|
27 | 27 | hetu_control_char <- function(pin, with.century = TRUE) {
|
28 |
| - |
29 |
| - if (length(pin) > 1){ |
| 28 | + |
| 29 | + if (length(pin) > 1) { |
30 | 30 | x <- vapply(pin,
|
31 | 31 | FUN = hetu_control_char,
|
32 | 32 | with.century = with.century,
|
33 | 33 | FUN.VALUE = character(1),
|
34 | 34 | USE.NAMES = FALSE)
|
35 | 35 | return(x)
|
36 | 36 | }
|
37 |
| - |
| 37 | + |
38 | 38 | checklist <- c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
39 | 39 | "A", "B", "C", "D", "E", "F", "H", "J", "K", "L",
|
40 | 40 | "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y")
|
41 | 41 | names(checklist) <- 0:30
|
42 |
| - |
43 |
| - if (with.century == TRUE){ |
44 |
| - if (nchar(pin) != 10){ |
| 42 | + |
| 43 | + if (with.century == TRUE) { |
| 44 | + if (nchar(pin) != 10) { |
45 | 45 | stop("Input PINs that only have 10 characters: birthdate, century marker
|
46 | 46 | and personal numbers (DDMMYYQZZZ)")
|
47 | 47 | }
|
48 |
| - if (!(substr(pin, start = 7, stop = 7) %in% c("-", "+", "A"))){ |
| 48 | + if (!(substr(pin, start = 7, stop = 7) %in% c("-", "+", "A"))) { |
49 | 49 | stop("7th character of your PIN needs to be a century marker (-, + or A).
|
50 | 50 | If your PIN does not have it use parameter with.century == FALSE")
|
51 | 51 | }
|
52 | 52 | pin_ddmmyy <- substr(pin, 1, 6)
|
53 | 53 | pin_zzz <- substr(pin, 8, 10)
|
54 |
| - } else if (with.century == FALSE){ |
55 |
| - if (nchar(pin) != 9){ |
| 54 | + } else if (with.century == FALSE) { |
| 55 | + if (nchar(pin) != 9) { |
56 | 56 | stop("Input PINs that only have 9 characters: birthdate and personal
|
57 | 57 | numbers (DDMMYYZZZ)")
|
58 | 58 | }
|
59 | 59 | pin_ddmmyy <- substr(pin, 1, 6)
|
60 | 60 | pin_zzz <- substr(pin, 7, 9)
|
61 | 61 | }
|
62 |
| - |
| 62 | + |
63 | 63 | mod <- as.numeric(paste0(pin_ddmmyy, pin_zzz)) %% 31
|
64 | 64 | extracted_control_char <- checklist[as.character(mod)]
|
65 | 65 | names(extracted_control_char) <- NULL
|
66 | 66 | extracted_control_char
|
67 |
| - |
| 67 | + |
68 | 68 | }
|
69 | 69 |
|
70 | 70 | #' @title Finnish Unique Identification Number Control Character Calculator
|
71 |
| -#' @description Calculate a valid control character for an incomplete |
| 71 | +#' @description Calculate a valid control character for an incomplete |
72 | 72 | #' Finnish Unique Identification Number (FINUID, or sähköinen asiointitunnus
|
73 | 73 | #' SATU).
|
74 |
| -#' @param pin An incomplete FINUID that has 8 numbers |
75 |
| -#' @param complement Should the function print only |
| 74 | +#' @param pin An incomplete FINUID that has 8 first numbers. |
| 75 | +#' @param print.full Should the function print only the whole FINUID-number |
| 76 | +#' (TRUE) or only the control character (FALSE). Default is FALSE. |
76 | 77 | #' @details This method of calculating the control character was devised by
|
77 |
| -#' mathematician Erkki Pale (1962) to detect input errors but also to |
78 |
| -#' detect errors produced by early punch card machines. The long number |
| 78 | +#' mathematician Erkki Pale (1962) to detect input errors but also to |
| 79 | +#' detect errors produced by early punch card machines. The long number |
79 | 80 | #' produced by writing the birth date and the personal number together are
|
80 | 81 | #' divided by 31 and the remainder is used to look up the control character
|
81 | 82 | #' from a separate table containing alphanumeric characters except letters
|
82 | 83 | #' G, I, O, Q and Z.
|
83 |
| -#' |
84 |
| -#' The method of calculating the control character does not need century |
| 84 | +#' |
| 85 | +#' The method of calculating the control character does not need century |
85 | 86 | #' character and therefore the function has an option to omit it.
|
86 |
| -#' @return Control character, either a number 0-9 or a letter. If complete |
87 |
| -#' is TRUE, then the function returns a complete FINUID / SATU number. |
88 |
| -#' @seealso |
89 |
| -#' For more detailed information about FINUID, see Finnish Digital and |
90 |
| -#' population data services agency website: |
| 87 | +#' @return Control character, either a number 0-9 or a letter (length 1 |
| 88 | +#' character). If parameter print.full is set to TRUE, the function returns |
| 89 | +#' a complete FINUID / SATU number (length 9 characters). |
| 90 | +#' @seealso |
| 91 | +#' For more detailed information about FINUID, see Finnish Digital and |
| 92 | +#' population data services agency website: |
91 | 93 | #' \url{https://dvv.fi/en/citizen-certificate-and-electronic-identity}
|
92 | 94 | #' @author Pyry Kantanen
|
93 | 95 | #' @examples
|
| 96 | +#' # The first assigned FINUID number, 10000001N. |
94 | 97 | #' satu_control_char("10000001")
|
95 | 98 | #' @export
|
96 |
| -satu_control_char <- function(pin, complement = FALSE) { |
| 99 | +satu_control_char <- function(pin, print.full = FALSE) { |
97 | 100 |
|
98 |
| - if (length(pin) > 1){ |
| 101 | + if (length(pin) > 1) { |
99 | 102 | x <- vapply(pin,
|
100 | 103 | FUN = satu_control_char,
|
101 |
| - complement = complement, |
| 104 | + print.full = print.full, |
102 | 105 | FUN.VALUE = character(1),
|
103 | 106 | USE.NAMES = FALSE)
|
104 | 107 | return(x)
|
105 | 108 | }
|
106 |
| - |
| 109 | + |
107 | 110 | checklist <- c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
108 | 111 | "A", "B", "C", "D", "E", "F", "H", "J", "K", "L",
|
109 | 112 | "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y")
|
110 | 113 | names(checklist) <- 0:30
|
111 | 114 |
|
112 |
| - if (nchar(pin) != 8){ |
| 115 | + if (nchar(pin) != 8) { |
113 | 116 | stop("Input FINUIDs that have 8 numbers")
|
114 | 117 | }
|
115 |
| - if (suppressWarnings(is.na(as.numeric(pin))) == TRUE){ |
| 118 | + if (suppressWarnings(is.na(as.numeric(pin))) == TRUE) { |
116 | 119 | stop("Input FINUIDs that only have numbers")
|
117 | 120 | }
|
118 |
| - |
| 121 | + |
119 | 122 | mod <- as.numeric(pin) %% 31
|
120 | 123 | extracted_control_char <- checklist[as.character(mod)]
|
121 | 124 | names(extracted_control_char) <- NULL
|
122 | 125 | extracted_control_char
|
123 |
| - |
124 |
| - if (complement == TRUE){ |
| 126 | + |
| 127 | + if (print.full == TRUE) { |
125 | 128 | paste0(pin, extracted_control_char)
|
126 | 129 | } else {
|
127 | 130 | extracted_control_char
|
|
0 commit comments