Skip to content

Commit

Permalink
Merge pull request #234 from chinapnr/v1.1.12_develop
Browse files Browse the repository at this point in the history
V1.1.12 develop
  • Loading branch information
itaa authored May 29, 2019
2 parents 564f8b5 + 158a5c1 commit 36fe477
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 53 deletions.
4 changes: 4 additions & 0 deletions docs/change_log.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
更新记录
===========================
2019.5.28 v1.1.12
---------------------------
* `#232 <https://github.com/chinapnr/fishbase/issues/232>`_, data, edit function :meth:`IdCard.get_zone_info`, :meth:`IdCard.get_areanote_info`, :meth:`IdCard.get_province_info`, :meth:`CardBin.get_bank_info`, :meth:`CardBin.get_cardbin_info`, optimize;

2019.5.14 v1.1.11
---------------------------
* `#229 <https://github.com/chinapnr/fishbase/issues/229>`_, random, edit function :meth:`fish_random.gen_random_bank_card` optimize;
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@
# built documents.
#
# The short X.Y version.
version = '1.1.11'
version = '1.1.12'
# The full version, including alpha/beta/rc tags.
release = '1.1.11'
release = '1.1.12'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion fishbase/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
from .fish_project import *
from .fish_random import *

__version__ = '1.1.10' # type: str
__version__ = '1.1.12' # type: str
92 changes: 49 additions & 43 deletions fishbase/fish_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@
import re
import sqlite3
import os
from functools import lru_cache


# 2018.12.18
def sqlite_query(db, sql, params):
dir_path = os.path.dirname(os.path.abspath(__file__))

conn = sqlite3.connect(os.path.join(dir_path, 'db', db))

cursor = conn.cursor()

cursor.execute(sql, params)

values = cursor.fetchall()

cursor.close()
conn.close()

return values


Expand Down Expand Up @@ -67,7 +68,7 @@ class IdCard(object):
---
"""

# 计算身份证号码的校验位
# ---
# 2018.12.12 create by David.Yi, add in v1.1.4 github issue #143
Expand Down Expand Up @@ -108,31 +109,31 @@ def get_checkcode(cls, id_number_str):
---
"""

# 判断长度,如果不是 17 位,直接返回失败
if len(id_number_str) != 17:
return False, -1

id_regex = '[1-9][0-9]{14}([0-9]{2}[0-9X])?'

if not re.match(id_regex, id_number_str):
return False, -1

items = [int(item) for item in id_number_str]

# 加权因子表
factors = (7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)

# 计算17位数字各位数字与对应的加权因子的乘积
copulas = sum([a * b for a, b in zip(factors, items)])

# 校验码表
check_codes = ('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')

checkcode = check_codes[copulas % 11].upper()

return True, checkcode

# 检查身份证号码是否能通过校验规则
# ---
# 2018.12.9 create by David Yi, add in v1.1.3, github issue #137
Expand Down Expand Up @@ -176,24 +177,25 @@ def check_number(cls, id_number):
"""
if isinstance(id_number, int):
id_number = str(id_number)

# 调用函数计算身份证前面17位的 checkcode
result = IdCard.get_checkcode(id_number[0:17])

# 返回第一个 flag 是错误的话,表示身份证格式错误,直接透传返回,第二个为获得的校验码
flag = result[0]
checkcode = result[1]

if not flag:
return flag,

# 判断校验码是否正确
return checkcode == id_number[-1].upper(),

# 输入包含省份、城市、地区信息的内容,返回地区编号,也就是身份证编码中的前6位内容
# ---
# 2018.12.14 12.16 create by David Yi, add in v1.1.4, github issue #139
@classmethod
@lru_cache()
def get_zone_info(cls, area_str, match_type='EXACT', result_type='LIST'):
"""
输入包含省份、城市、地区信息的内容,返回地区编号;
Expand Down Expand Up @@ -255,33 +257,34 @@ def get_zone_info(cls, area_str, match_type='EXACT', result_type='LIST'):
"""
values = []

if match_type == 'EXACT':
values = sqlite_query('fish_data.sqlite',
'select zone, areanote from cn_idcard where areanote = :area', {"area": area_str})
if match_type == 'FUZZY':
values = sqlite_query('fish_data.sqlite',
'select zone, areanote from cn_idcard where areanote like :area',
{"area": '%' + area_str + '%'})

# result_type 结果数量判断处理

if result_type == 'LIST':
# 如果返回记录多,大于 20 项,只返回前面 20 个结果
if len(values) > 20:
values = values[0:20]

return values

if result_type == 'SINGLE_STR':
if len(values) == 0:
return ''
if len(values) > 0:
value_str = values[0][0]
return value_str

# 2019.01.07 create by Hu Jun, add in v1.1.6, github issue #192
@classmethod
@lru_cache()
def get_areanote_info(cls, province):
"""
输入省份代码,返回地区信息;
Expand Down Expand Up @@ -314,9 +317,10 @@ def get_areanote_info(cls, province):
'select zone, areanote from cn_idcard where province = :province ',
{"province": province})
return values

# 2019.01.14 create by Hu Jun, add in v1.1.6, github issue #192
@classmethod
@lru_cache()
def get_province_info(cls):
"""
获取省份代码
Expand All @@ -325,7 +329,7 @@ def get_province_info(cls):
:returns:
* province_list: (list) 省份代码列表
举例如下::
from fishbase.fish_data import *
Expand Down Expand Up @@ -381,7 +385,7 @@ class CardBin(object):
---
"""

# 计算银行卡校验位
# ---
# 2018.12.18 create by David Yi, v1.1.4, github issue #154
Expand Down Expand Up @@ -416,7 +420,7 @@ def get_checkcode(cls, card_number_str):
"""
total = 0
even = True

for item in card_number_str[-1::-1]:
item = int(item)
if even:
Expand All @@ -425,11 +429,11 @@ def get_checkcode(cls, card_number_str):
item -= 9
total += item
even = not even

checkcode = (10 - (total % 10)) % 10

return str(checkcode)

# 检查银行卡校验位是否正确
# ---
# 2018.12.18 create by David Yi, v1.1.4, github issue #155
Expand Down Expand Up @@ -462,21 +466,22 @@ def check_bankcard(cls, card_number_str):
---
"""

if isinstance(card_number_str, int):
card_number_str = str(card_number_str)

checkcode = card_number_str[-1]

result = CardBin.get_checkcode(card_number_str[0:-1])

return checkcode == result

# 输入银行名称,返回银行代码
# ---
# 2018.12.18 create by David Yi, add in v1.1.4, github issue #159
# 2019.1.5 edit, v1.1.6 github issue #188, 修改函数名称
@classmethod
@lru_cache()
def get_bank_info(cls, bankname):
"""
银行名称,返回银行代码;
Expand Down Expand Up @@ -506,14 +511,15 @@ def get_bank_info(cls, bankname):
values = sqlite_query('fish_data.sqlite',
'select bankcode,bankname from cn_bank where bankname=:bankname',
{"bankname": bankname})

return values

# 输入银行、借记贷记卡种类,返回有效的卡 bin
# ---
# 2018.12.17 create by David Yi, add in v1.1.4, github issue #149
# 2019.1.5 edit, v1.1.6 github issue #188, 修改函数名称
@classmethod
@lru_cache()
def get_cardbin_info(cls, bank, card_type):
"""
输入银行、借记贷记卡种类,返回有效的卡 bin;
Expand Down Expand Up @@ -547,5 +553,5 @@ def get_cardbin_info(cls, bank, card_type):
'select bin,bankcode,cardtype,length from cn_cardbin where bankcode=:bank '
'and cardtype=:card_type',
{"bank": bank, "card_type": card_type})

return values
22 changes: 15 additions & 7 deletions fishbase/fish_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ def gen_random_float(minimum, maximum, decimals=2):

# v1.1.6 edit by Hu Jun #204
# v1.1.5 edit by Hu Jun #173
# v1.1.12 edit by Hu Jun #232
def get_random_areanote(zone):
"""
省份行政区划代码,返回下辖的随机地区名称
Expand Down Expand Up @@ -271,11 +272,12 @@ def get_random_areanote(zone):
if not (areanote_list and province_name_list):
raise ValueError('zone error, please check and try again')

# 只选取下辖区域
areanote_list.remove(province_name_list[0])

province_name = province_name_list[0][-1]
random_areanote = random.choice(areanote_list)
while True:
random_areanote = random.choice(areanote_list)
# 只选取下辖区域
if random_areanote != province_name_list[0]:
break
full_areanote = random_areanote[-1]
return full_areanote.split(province_name)[-1]

Expand Down Expand Up @@ -447,6 +449,7 @@ def gen_random_bank_card(bank_name=None, card_type=None):


# v1.1.5 edit by Hu Jun #165
# v1.1.12 edit by Hu Jun #232
def gen_random_id_card(zone=None, gender=None, age=None, result_type='SINGLE_STR'):
"""
根据指定的省份编号、性别或年龄,随机生成一个身份证号
Expand Down Expand Up @@ -488,11 +491,11 @@ def gen_random_id_card(zone=None, gender=None, age=None, result_type='SINGLE_STR
areanote_list = IdCard.get_areanote_info(province)

# 判断 zone 是否合法
if zone and (zone not in set([item[0] for item in areanote_list])):
if zone[:2] != '0000' and zone not in [item[0] for item in areanote_list]:
raise ValueError('zone {} error, check and try again'.format(zone))

# 删除省份编号,身份证前缀不包含省份编号
areanote_list.remove([item for item in areanote_list if item[0] == zone][0])
# areanote_list.remove([item for item in areanote_list if item[0] == zone][0])

zone_list = [item[0] for item in areanote_list]

Expand All @@ -518,7 +521,12 @@ def gen_random_id_card(zone=None, gender=None, age=None, result_type='SINGLE_STR
birth = GetRandomTime.gen_date_by_range(start_date_str, now_date_str, date_format="%Y%m%d")
birth = str(int(year) - age) + birth[4:]

zone = random.choice(zone_list)
while True:
zone = random.choice(zone_list)
# 身份证前缀不包含省份编号
if zone[2:] != '0000':
break

random_str = str(random.randint(10, 99))
gender_str = str(random.choice(gender_dict.get(gender)))
_, check_code = IdCard.get_checkcode(zone + birth + random_str + gender_str)
Expand Down

0 comments on commit 36fe477

Please sign in to comment.