The Jade In the mountains can be reconstructed: ID card number parsing, verification tool 3 (the third day)

Source: Internet
Author: User

The progress in the previous two days seems to be a little slow. Today, we have accelerated a little bit, so we will not detail each step.

= Extraction of Area Information

After gender and birthday, the last information block will only list the tests as follows.


(Copyright: 2012-2013 Yu qin'an)

= "Validity

This is a big problem. previously, I temporarily removed the verification from different places. the original author of the Code also talked about his views on verification. he is right. This completely verified method is basically the design idea of DDD. However, I want to say that my knowledge is temporarily removed to ensure the unit of testing. The verification function is driven by the verification test. The second consideration is that my verification is intended to be placed in the constructor. That is to say, if there is any wrong input, the first door cannot be entered.

Here, the test and implementation are both simple and look like a lot, just some listing, different error scenarios.

[Subject ("ID card, validity")] public class when_create_social_id_with_valid_format {private because of = () => subject = new socialid ("430103123456780020"); Private it should_create_social_properly = () => subject. getcardnumber (). shouldequal ("430103123456780020"); Private Static socialid subject;} [subject ("ID card, validity")] public class when_create_social_id_with_null_string {private because of = () => exception = catch. exception () => New socialid (null); Private it should_not_allow_to_create = () => exception. shouldnotbenull (); Private Static socialid subject; Private Static exception;} [subject ("ID card, validity")] public class when_create_social_id_with_empty_string {private because of = () => exception = catch. exception () => New socialid (string. empty); Private it should_not_allow_to_create = () => exception. shouldnotbenull (); Private Static socialid subject; Private Static exception;} [subject ("ID card, validity")] public class when_create_social_id_with2_length_string {private because of = () => exception = catch. exception () => New socialid ("12"); Private it should_not_allow_to_create = () => exception. shouldnotbenull (); Private Static socialid subject; Private Static exception;} [subject ("ID card, validity")] public class when_create_social_id_with_20_length_string {private because of = () => exception = catch. exception () => New socialid ("12345678901234567890"); Private it should_not_allow_to_create = () => exception. shouldnotbenull (); Private Static socialid subject; Private Static exception;} [subject ("ID card, validity")] public class when_create_social_id_alphet_length_string {private because of = () => exception = catch. exception () => New socialid ("a23456789012345678"); Private it should_not_allow_to_create = () => exception. shouldnotbenull (); Private Static socialid subject; Private Static exception ;}

Implementation

public SocialID(String cardNumber)        {            if (string.IsNullOrEmpty(cardNumber))                throw new ApplicationException("Card Number is empty");            if (cardNumber.Length != CARD_NUMBER_LENGTH)                throw new ApplicationException("Card Number Length is wrong.");            if (!SOCIAL_NUMBER_PATTERN.IsMatch(cardNumber))                throw new ApplicationException("Card Number has wrong charactor(s).");                  }
= "Verification code"

The verification code is a special validity check, which is complicated. Here, I extract this part of logic code into a validator.

The test is extremely simple, and the implementation is almost intact.

Test:

public class when_verify_soical_number:Specification<Verifier>    {        Because of = () => { code = subject.verify("43010319791211453"); };        private It verify_code_should_match =            () => code.ShouldEqual('4');        private static char code;    }

Implementation

Namespace skight. eliteweb. domain. specs. properties {public class verifier {Private Static char [] verify_code = {'1', '0', 'x', '9', '8', '7 ', '6', '5', '4', '3', '2'};/*** 18-digit ID card, value of the verification code generated by each number */Private Static int [] verify_code_weight = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; Private Static int card_number_length = 18; Public char verify (string source) {/*** <li> Verification Code (18th digits ): <br/> * <ul> * <li> the weighted summation formula S = sum (ai * WI), I = 0... 16. First, sum the weights of the first 17 digits. * Ai: indicates the ID card number at position I. Digital value wi: indicates the Weighted Factor wi at position I: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4*2; </LI> * <li> computing mode y = Mod (S, 11) </LI> * <li> use the modulo to obtain the corresponding verification code Y: 0 1 2 3 4 5 6 7 8 9 10: 1 0x9 8 7 6 5 4 3 2 </LI> * </ul> ** @ Param cardNumber * @ return */INT sum = 0; for (INT I = 0; I <card_number_length-1; I ++) {char CH = source [I]; sum + = (INT) (CH-'0') * verify_code_weight [I];} return verify_code [Sum % 11] ;}}

At this time, the complete implementation of the ID card constructor becomes

public SocialID(String cardNumber)        {            if (string.IsNullOrEmpty(cardNumber))                throw new ApplicationException("Card Number is empty");            if (cardNumber.Length != CARD_NUMBER_LENGTH)                throw new ApplicationException("Card Number Length is wrong.");            if (!SOCIAL_NUMBER_PATTERN.IsMatch(cardNumber))                throw new ApplicationException("Card Number has wrong charactor(s).");            if (cardNumber[CARD_NUMBER_LENGTH - 1] != verifier.verify(cardNumber))                throw new ApplicationException("Card Number verified code is not match.");            this.cardNumber = cardNumber;        }

So far, the code is very clean. Yes, there are further improvements. For example, the extraction of the three elements (Region, birthday, and gender) should be moved to the constructor. The extraction function is changed to simple data reading. The type of social, instead of class, is struct, because it is a typical value object. In addition, I removed the 15-to-18-bit portion, which can be regarded as a utilit and can be done externally, not a core function.

Can you continue?

Finally, let's take a look at the test results:


Complete code:

Socialid. CS

Verifier. CS

(The Copyright in this article is 2012-2013 Yu Qinan | repost the article to indicate the author and source)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.