Browse Source

Merge pull request #31 from ssfjhh/addChinaPatentNumberValidation

Add china patent number validation
懒得勤快 5 năm trước cách đây
mục cha
commit
a0bbac815f

+ 103 - 0
Masuit.Tools.Abstractions/Extensions/BaseType/StringExtensions.cs

@@ -506,5 +506,108 @@ namespace Masuit.Tools
         }
 
         #endregion Crc32
+
+        #region 权威校验中国专利申请号/专利号
+        /// <summary>
+        /// 中国专利申请号(授权以后就是专利号)由两种组成
+        /// 2003年9月30号以前的9位(不带校验位是8号),校验位之前可能还会有一个点,例如:00262311, 002623110 或 00262311.0
+        /// 2003年10月1号以后的13位(不带校验位是12号),校验位之前可能还会有一个点,例如:200410018477, 2004100184779 或200410018477.9
+        /// http://www.sipo.gov.cn/docs/pub/old/wxfw/zlwxxxggfw/hlwzljsxt/hlwzljsxtsyzn/201507/P020150713610193194682.pdf
+        /// 上面的文档中均不包括校验算法,但是下面的校验算法没有问题
+        /// </summary>
+        /// <param name="patnum">源字符串</param>
+        /// <returns>是否匹配成功</returns>
+        public static bool MatchCNPatentNumber(this string patnum)
+        {
+            Regex patnumWithCheckbitPattern = new Regex(@"^
+(?<!\d)
+(?<patentnum>
+    (?<basenum>
+        (?<year>(?<old>8[5-9]|9[0-9]|0[0-3])|(?<new>[2-9]\d{3}))
+        (?<sn>
+            (?<patenttype>[12389])
+            (?(old)\d{5}|(?(new)\d{7}))
+        )
+    )
+    (?:
+    \.?
+    (?<checkbit>[0-9X])
+    )?
+)
+(?!\d)
+$", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase | RegexOptions.Multiline);
+            Match m = patnumWithCheckbitPattern.Match(patnum);
+            if (!m.Success)
+            {
+                return false;
+            }
+            bool isPatnumTrue = true;
+            patnum = patnum.ToUpper().Replace(".", "");
+            if (patnum.Length == 9 || patnum.Length == 8)
+            {
+                byte[] factors8 = new byte[8] { 2, 3, 4, 5, 6, 7, 8, 9 };
+                int year = Convert.ToUInt16(patnum.Substring(0, 2));
+                year += (year >= 85) ? (ushort)1900u : (ushort)2000u;
+                if (year >= 1985 || year <= 2003)
+                {
+                    int sum = 0;
+                    for (byte i = 0; i < 8; i++)
+                    {
+                        sum += factors8[i] * (patnum[i] - '0');
+                    }
+                    char checkbit = "0123456789X"[sum % 11];
+                    if (patnum.Length == 9)
+                    {
+                        if (checkbit != patnum[8])
+                        {
+                            isPatnumTrue = false;
+                        }
+                    }
+                    else
+                    {
+                        patnum += checkbit;
+                    }
+                }
+                else
+                {
+                    isPatnumTrue = false;
+                }
+            }
+            else if (patnum.Length == 13 || patnum.Length == 12)
+            {
+                byte[] factors12 = new byte[12] { 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5 };
+                int year = Convert.ToUInt16(patnum.Substring(0, 4));
+                if (year >= 2003 && year <= DateTime.Now.Year)
+                {
+                    int sum = 0;
+                    for (byte i = 0; i < 12; i++)
+                    {
+                        sum += factors12[i] * (patnum[i] - '0');
+                    }
+                    char checkbit = "0123456789X"[sum % 11];
+                    if (patnum.Length == 13)
+                    {
+                        if (checkbit != patnum[12])
+                        {
+                            isPatnumTrue = false;
+                        }
+                    }
+                    else
+                    {
+                        patnum += checkbit;
+                    }
+                }
+                else
+                {
+                    isPatnumTrue = false;
+                }
+            }
+            else
+            {
+                isPatnumTrue = false;
+            }
+            return isPatnumTrue;
+        }
     }
+    #endregion
 }