Last active
March 1, 2016 01:28
-
-
Save sgr-ksmt/8e2385c53c595a7c8333 to your computer and use it in GitHub Desktop.
マイナンバーのチェックデジットをSwiftで計算する ref: http://qiita.com/su_k/items/4b442e3094fdea031065
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum ValidationResult { | |
case Success | |
case Failure(ValidationErrorType) | |
} | |
enum ValidationErrorType: ErrorType { | |
case WrongLength(Int) // マイナンバーの桁数(文字数)が不正の場合 | |
case NotANumber // 数字以外が含まれている場合 | |
case InvalidNumber // 検査して不正なマイナンバーだった場合 | |
} | |
// 便宜上関数名末尾に2をつけています。 | |
func validateMyNumber2(numstr: String) -> ValidationResult { | |
let length = numstr.utf8.count | |
if length != 12 { | |
return ValidationResult.Failure(.WrongLength(length)) | |
} | |
let exp = try! NSRegularExpression(pattern: "^[0-9]+$", options: []) | |
if exp.matchesInString(numstr, options: [], range: NSMakeRange(0, length)).count == 0 { | |
return ValidationResult.Failure(.NotANumber) | |
} | |
var characters = numstr.characters.map{ String($0) } | |
let checkDigit = Int(characters.removeLast())! | |
var pq = 0 | |
for (index, num) in characters.reverse().enumerate() { | |
let n = index + 1 | |
let p = Int(num)! | |
let q = (n >= 7) ? n - 5 : n + 1 | |
pq += p * q | |
} | |
let remainder = pq % 11 | |
let valid = (remainder <= 1) ? (checkDigit == 0) : (checkDigit == (11 - remainder)) | |
return valid ? ValidationResult.Success : ValidationResult.Failure(.InvalidNumber) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func validateMyNumber(numstr: String) -> Bool { | |
// 桁数チェック | |
let length = numstr.utf8.count | |
if length != 12 { | |
return false | |
} | |
// 正規表現を使って数字のみかどうかチェック | |
let exp = try! NSRegularExpression(pattern: "^[0-9]+$", options: []) | |
if exp.matchesInString(numstr, options: [], range: NSMakeRange(0, length)).count == 0 { | |
return false | |
} | |
// 扱いやすいように一旦Stringを1文字ずつ分割 | |
var characters = numstr.characters.map{ String($0) } | |
// チェックデジットをcharactersからpop | |
// pop後はcharactersの中身は12->11個になります。 | |
let checkDigit = Int(characters.removeLast())! | |
// 検査用数字の計算 | |
var pq = 0 | |
for (index, num) in characters.reverse().enumerate() { | |
let n = index + 1 | |
let p = Int(num)! | |
let q = (n >= 7) ? n - 5 : n + 1 | |
pq += p * q | |
} | |
// 検査 | |
let remainder = pq % 11 | |
return (remainder <= 1) ? (checkDigit == 0) : (checkDigit == (11 - remainder)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 上記ソースの後に貼っても動くように便宜上"__"をつけておきます。 | |
func __validateMyNumber(numstr: String) throws -> Bool { | |
let length = numstr.utf8.count | |
if length != 12 { | |
throw ValidationErrorType.WrongLength(length) | |
} | |
let exp = try! NSRegularExpression(pattern: "^[0-9]+$", options: []) | |
if exp.matchesInString(numstr, options: [], range: NSMakeRange(0, length)).count == 0 { | |
throw ValidationErrorType.NotANumber | |
} | |
var characters = numstr.characters.map{ String($0) } | |
let checkDigit = Int(characters.removeLast())! | |
var pq = 0 | |
for (index, num) in characters.reverse().enumerate() { | |
let n = index + 1 | |
let p = Int(num)! | |
let q = (n >= 7) ? n - 5 : n + 1 | |
pq += p * q | |
} | |
let remainder = pq % 11 | |
return (remainder <= 1) ? (checkDigit == 0) : (checkDigit == (11 - remainder)) | |
} | |
func tryValidation(numstr: String) { | |
do { | |
let valid = try __validateMyNumber(numstr) | |
print("\(numstr) is",(valid ? "valid" : "invalid")) | |
} catch ValidationErrorType.WrongLength(let length) { | |
print("\(numstr) is wrong length: \(length)") | |
} catch ValidationErrorType.NotANumber { | |
print("\(numstr) is not a number") | |
} catch { | |
print("unknown error occurred") | |
} | |
} | |
tryValidation("123456789012") // => "123456789012 is invalid\n" | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
validateMyNumber("1234567890123") // => false | |
validateMyNumber("123456789010") // => false | |
validateMyNumber("A23456789010") // => false | |
validateMyNumber("123456789010") // => false | |
validateMyNumber("123456789011") // => false | |
validateMyNumber("123456789012") // => false | |
validateMyNumber("123456789013") // => false | |
validateMyNumber("123456789014") // => false | |
validateMyNumber("123456789015") // => false | |
validateMyNumber("123456789016") // => false | |
validateMyNumber("123456789017") // => false | |
validateMyNumber("123456789018") // => true | |
validateMyNumber("123456789019") // => false | |
validateMyNumber("023456789013") // => true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
validateMyNumber2("1234567890123") // -> Failure(ValidationErrorType.WrongLength(13)) | |
validateMyNumber2("123456789010") // -> Failure(ValidationErrorType.WrongLength(36)) | |
validateMyNumber2("A23456789010") // => Failure(ValidationErrorType.NotANumber) | |
validateMyNumber2("123456789010") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789011") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789012") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789013") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789014") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789015") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789016") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789017") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("123456789018") // => Success | |
validateMyNumber2("123456789019") // => Failure(ValidationErrorType.InvalidNumber) | |
validateMyNumber2("023456789013") // => Success |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment