LoginSignup
9
8

More than 5 years have passed since last update.

マイナンバーのチェックディジットをObjective-Cで計算する

Last updated at Posted at 2016-02-29

マイナンバーのチェックデジットを計算するの記事を参考に、有志によって様々な言語用にコードが書かれていますが、Objective-Cのコードがなかったので書いてみました。

NSString+ValidateMyNumber.h
#import <Foundation/Foundation.h>

@interface NSString (ValidateMyNumber)

@property (readonly) BOOL isValidMyNumber;

- (BOOL)isValidMyNumber;
+ (BOOL)isValidMyNumber:(NSString *)myNumber;

@end
NSString+ValidateMyNumber.m
#import "NSString+ValidateMyNumber.h"

@implementation NSString (ValidateMyNumber)

- (BOOL)isValidMyNumber {
    return [NSString isValidMyNumber:self];
}

+ (BOOL)isValidMyNumber:(NSString *)myNumber {

    // 12桁であるかのチェック
    if (myNumber.length != 12) {
        return NO;
    }

    // 数字のみであるかのチェック
    NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:myNumber];
    if (![[NSCharacterSet decimalDigitCharacterSet] isSupersetOfSet:characterSet]) {
        return NO;
    }

    // チェックディジット取得
    NSInteger checkDigit = [myNumber substringFromIndex:11].integerValue;

    // チェックディジットを除く数字を1文字ずつ配列に入れる
    NSMutableArray<NSString *> *digits = [NSMutableArray arrayWithCapacity:11];
    [myNumber enumerateSubstringsInRange:NSMakeRange(0, 11)
                                 options:NSStringEnumerationByComposedCharacterSequences | NSStringEnumerationReverse
                              usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
                                  [digits addObject:substring];
                              }];

    // 数列の和を11で割った余りを計算
    NSInteger sum = 0;
    NSInteger n = 1;
    for (NSString *digit in digits) {
        NSInteger p = digit.integerValue;
        NSInteger q = n <= 6 ? n + 1 : n - 5;
        sum += p * q;
        n++;
    }

    NSInteger remainder = sum % 11;
    return remainder <= 1 ? checkDigit == 0 : checkDigit == (11 - remainder);
}

@end

使い方

NSStringのカテゴリにしてあります。

使い方サンプル1
NSString *myNumber = @"123456789018";
BOOL valid = myNumber.isValidMyNumber; // or [myNumber isValidMyNumber];
使い方サンプル2
BOOL valid = [NSString isValidMyNumber:@"123456789018"];

テストコード

ValidateMyNumberTests.m
#import <XCTest/XCTest.h>
#import "NSString+ValidateMyNumber.h"

@interface ValidateMyNumberTests : XCTestCase

@end

@implementation ValidateMyNumberTests

- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void)testMyNumber {
    XCTAssertFalse(@"123456789010".isValidMyNumber);
    XCTAssertFalse(@"123456789011".isValidMyNumber);
    XCTAssertFalse(@"123456789012".isValidMyNumber);
    XCTAssertFalse(@"123456789013".isValidMyNumber);
    XCTAssertFalse(@"123456789014".isValidMyNumber);
    XCTAssertFalse(@"123456789015".isValidMyNumber);
    XCTAssertFalse(@"123456789016".isValidMyNumber);
    XCTAssertFalse(@"123456789017".isValidMyNumber);
    XCTAssertTrue(@"123456789018".isValidMyNumber); // true
    XCTAssertFalse(@"123456789019".isValidMyNumber);
    XCTAssertTrue(@"023456789013".isValidMyNumber); // true
}

@end

マイナンバーのチェックデジットの詳細については元ネタをどうぞ。

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8