xml地图|网站地图|网站标签 [设为首页] [加入收藏]
Python2中文处理纪要,Django思维导图
分类:编程

需要说明的是这里的大陆身份证识别并不是公安局联网的识别,而是按国标GB 11643进行的验证,所以其验证结果只能说符合国标规范,但不能保证该身份证一定真实存在,如果你实际需求是希望身份证一定真实存在,那么你可以在通过此类库初步验证后,再调用第三方(或牛逼的可以直连公安,毕竟所有的第三方其数据来源必定是公安局)以降低调用成本(公安调用一次两块钱,还不是有钱就能调用!!!)

python2不是以unicode作为基本代码字符类型,碰到乱码的几率是远远高于python3,但即便如此,相信很多人,也不想随意的迁移到python3,这里就总结几个我平常碰到的问题及解法。

查看方式:右键-“新标签页打开图片”-“放大”

转到正题,在NumberValidators中,大陆身份证相关的代码均在NumberValidators.IdentityCards下,具体的验证实现为:ID18Validator(第二代身份证,长度为18),ID15Validator(第一代身份证,长度为15),而IDValidatorHelper则为所有实现了IIDValidator(身份证识别接口)且完全按照 ID{Length}Validator 格式命名的身份证识别自动适配静态类(Length为证件号码长度),除基础的验证外,还提供了TryPromotion方法(一代身份证升位成二代身份证)

  1. 文件中无法使用中文注释
    处理方法:
    在代码中增加# -*- coding=UTF-8 -*-,一般加在文件头部第一行,如果第一行是脚本标志,则放在第二行(实际仍然是python正本的第一行)。
    随后将文件另存为UTF-8格式。
    此方法可以解决注释中有中文,及字符串立即数中包含中文的问题。

  2. unicode中文变量打印出来是乱码
    处理方法:
    文件开始引入扩展库的部分加入以下3行代码。

图片 1

IIDValidator(身份证识别接口)定义如下

 

    /// <summary>
    /// 所有号码验证类均需实现的基础接口定义
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IValidator<out T>
        where T : ValidationResult, new()
    {
        /// <summary>
        /// 随机生成一个符合规则的号码
        /// </summary>
        /// <returns></returns>
        string GenerateRandomNumber();
        /// <summary>
        /// 验证号码是否正确
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        T Validate(string number);
    }

    /// <summary>
    /// 身份证验证接口
    /// </summary>
    public interface IIDValidator : IValidator<IDValidationResult>
    {
        /// <summary>
        /// 用于验证的字典数据
        /// </summary>
        IValidationDictionary<int, string> Dictionary { get; set; }
        /// <summary>
        /// 生成身份证号码
        /// </summary>
        /// <param name="areaNumber">行政区划编号</param>
        /// <param name="birthDay">出生日期</param>
        /// <param name="sequenceNumber">顺序号</param>
        /// <returns></returns>
        string GenerateID(int areaNumber, DateTime birthDay, int sequenceNumber);
        /// <summary>
        /// 验证身份证是否正确
        /// </summary>
        /// <param name="idNumber">待验证的证件号码</param>
        /// <param name="minYear">允许最小年份,默认0</param>
        /// <param name="validLimit">验证区域级别,默认AreaValidLimit.Province</param>
        /// <param name="ignoreCheckBit">是否忽略校验位验证,默认false</param>
        /// <returns>验证结果</returns>
        IDValidationResult Validate(string idNumber, ushort minYear = 0, AreaValidLimit validLimit = AreaValidLimit.Province, bool ignoreCheckBit = false);
    }  
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

验证结果IDValidationResult定义如下

  1. utf-8 及 gbk互相转换
    直接看代码:
    /// <summary>
    /// 号码验证结果类
    /// </summary>
    public class ValidationResult
    {
        /// <summary>
        /// 验证结果是否通过
        /// </summary>
        public bool IsValid { get; internal set; } = true;
        /// <summary>
        /// 如果验证不通过,这里包含验证失败的原因
        /// </summary>
        public IList<string> Errors { get; internal set; } = new List<string>();
        /// <summary>
        /// 当前验证的号码
        /// </summary>
        public string Number { get; internal set; }

        /// <summary>
        /// 添加错误信息
        /// </summary>
        /// <param name="errorMsg"></param>
        /// <param name="parameters"></param>
        internal void AddErrorMessage(string errorMsg, params object[] parameters)
        {
            if (parameters != null && parameters.Length > 0)
            {
                errorMsg = string.Format(errorMsg, parameters);
            }
            this.Errors.Add(errorMsg);
            this.IsValid = false;
        }
    }

    /// <summary>
    /// 身份证验证结果类
    /// </summary>
    public class IDValidationResult : ValidationResult
    {
        /// <summary>
        /// 身份证号码长度
        /// </summary>
        public IDLength IDLength { get; internal set; }
        /// <summary>
        /// 身份证上的出生日期
        /// </summary>
        public DateTime Birthday { get; internal set; }
        /// <summary>
        /// 性别
        /// </summary>
        public Gender Gender { get; internal set; }
        /// <summary>
        /// 行政区划编码
        /// </summary>
        public int AreaNumber { get; internal set; }
        /// <summary>
        /// 身份证颁发行政区域(识别出Depth最深的区域),可通过FullName来获取完整的区域名
        /// </summary>
        public Area RecognizableArea { get; internal set; }
        /// <summary>
        /// 出生登记顺序号
        /// </summary>
        public int Sequence { get; internal set; }
        /// <summary>
        /// 身份证校验码
        /// </summary>
        public char CheckBit { get; internal set; }
    }

可以根据 IsValid 属性来判断是否验证通过(true/false),如果验证失败,Errors 属性则包含了验证失败的原因,具体的错误原因列表如下

#utf-8字符串转换成GBK(GB2312及其它编码也是这样用)
print str.decode('UTF-8').encode('GBK')
#gbk转换成utf-8
print str.decode('GBK').encode('UTF-8')
        /// <summary>
        /// 身份证号码为空
        /// </summary>
        public const string Empty = "身份证号码为空";
        /// <summary>
        /// 错误的身份证号码
        /// </summary>
        public const string Error = "错误的身份证号码";
        /// <summary>
        /// 无效的出生日期
        /// </summary>
        public const string InvalidBirthday = "无效的出生日期";
        /// <summary>
        /// 出生日期超出允许的年份范围
        /// </summary>
        public const string BirthdayYearOutOfRange = "出生日期超出允许的年份范围{0} ~ {1}";
        /// <summary>
        /// 行政区划识别失败
        /// </summary>
        public const string InvalidArea = "行政区划识别失败";
        /// <summary>
        /// 行政区划识别度不足
        /// </summary>
        public const string AreaLimitOutOfRange = "行政区划识别度低于识别级别 {0}";
        /// <summary>
        /// 错误的校验码
        /// </summary>
        public const string InvalidCheckBit = "错误的校验码";
        /// <summary>
        /// 无效实现
        /// </summary>
        public const string InvalidImplement = "未能找到或无效的 {0} 位身份证实现";
        /// <summary>
        /// 长度错误
        /// </summary>
        public const string LengthOutOfRange = "身份证号码非 {0} 位";
  1. 参数中的utf-8是用大写还是小写?
    通常大小写都可以,这不是python决定的,是系统的语言代码设定决定的。

  2. 打开utf-8的文本文件
    经过1、2的设置,正常直接打开就可以,文件是什么编码,读出来就是什么编码,个别仍有不行的可以使用扩展库codecs:

而验证通过时,你可以通过通过其它属性来获取一些你可能感兴趣的信息,比如 Birthday(出生日期)、Gender(性别)、RecognizableArea(识别出的完整区域,你可以通过其FullName获取完整的行政区域名称,比如  上海市市辖区徐汇区)等等……

本文由澳门新葡亰手机版发布于编程,转载请注明出处:Python2中文处理纪要,Django思维导图

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文