diff --git a/faker/providers/ssn/zh_CN/__init__.py b/faker/providers/ssn/zh_CN/__init__.py index 69d5c93723..30bf868d87 100644 --- a/faker/providers/ssn/zh_CN/__init__.py +++ b/faker/providers/ssn/zh_CN/__init__.py @@ -9,6 +9,7 @@ class Provider(SsnProvider): # Extracted from # http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201504/t20150415_712722.html + # 《港澳台居民居住证申领发放办法》https://www.gov.cn/zhengce/content/2018-08/19/content_5314865.htm area_codes: List[str] = [ "110000", "110100", @@ -3522,13 +3523,17 @@ class Provider(SsnProvider): "710000", "810000", "820000", + "830000", ] - def ssn(self, min_age: int = 18, max_age: int = 90, gender: Optional[SexLiteral] = None) -> str: + def ssn( + self, min_age: int = 18, max_age: int = 90, gender: Optional[SexLiteral] = None, area_code: str = "" + ) -> str: """ Return 18 character chinese personal identity code :param gender: F for female M for male None for default + :param area_code: None for default """ def checksum(s): @@ -3538,7 +3543,9 @@ def checksum(s): birthday = datetime.date.today() - age birthday_str = birthday.strftime("%Y%m%d") - area_code: str = self.random_element(self.area_codes) + if area_code not in self.area_codes: + area_code = self.random_element(self.area_codes) + ssn_without_checksum = self.numerify(area_code + birthday_str + "##") _number = ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9") diff --git a/tests/providers/test_ssn.py b/tests/providers/test_ssn.py index 83ec059576..b41f08d206 100644 --- a/tests/providers/test_ssn.py +++ b/tests/providers/test_ssn.py @@ -1229,6 +1229,33 @@ def test_zh_CN_ssn_gender_passed(self): ssn = self.fake.ssn(gender="M") assert int(ssn[16]) % 2 == 1 + def test_zh_CN_ssn_invalid_area_code_passed(self): + ssn = self.fake.ssn(area_code=12) + assert int(ssn[0:6]) > 0 + + ssn = self.fake.ssn(area_code={}) + assert int(ssn[0:6]) > 0 + + ssn = self.fake.ssn(area_code=[]) + assert int(ssn[0:6]) > 0 + + ssn = self.fake.ssn(area_code=None) + assert int(ssn[0:6]) > 0 + + ssn = self.fake.ssn() + assert int(ssn[0:6]) > 0 + + def test_zh_CN_ssn_area_code_passed(self): + # + ssn = self.fake.ssn(area_code="654225") + assert int(ssn[0:6]) == 654225 + + ssn = self.fake.ssn(area_code="820000") + assert int(ssn[0:6]) == 820000 + + ssn = self.fake.ssn(area_code="830000") + assert int(ssn[0:6]) == 830000 + class TestRoRO(unittest.TestCase): """Tests SSN in the ro_RO locale"""