如何validationUPC或EAN代码?

我需要一个C#.NET函数来评估键入或扫描的条形码是否是有效的全球贸易项目编号 (UPC或EAN)。

条形码检查数字

条形码编号的最后一位是计算机校验位,可确保条形码正确合成。 GTIN校验数字计算器

public static bool IsValidGtin(string code) { if (code != (new Regex("[^0-9]")).Replace(code, "")) { // is not numeric return false; } // pad with zeros to lengthen to 14 digits switch (code.Length) { case 8: code = "000000" + code; break; case 12: code = "00" + code; break; case 13: code = "0" + code; break; case 14: break; default: // wrong number of digits return false; } // calculate check digit int[] a = new int[13]; a[0] = int.Parse(code[0].ToString()) * 3; a[1] = int.Parse(code[1].ToString()); a[2] = int.Parse(code[2].ToString()) * 3; a[3] = int.Parse(code[3].ToString()); a[4] = int.Parse(code[4].ToString()) * 3; a[5] = int.Parse(code[5].ToString()); a[6] = int.Parse(code[6].ToString()) * 3; a[7] = int.Parse(code[7].ToString()); a[8] = int.Parse(code[8].ToString()) * 3; a[9] = int.Parse(code[9].ToString()); a[10] = int.Parse(code[10].ToString()) * 3; a[11] = int.Parse(code[11].ToString()); a[12] = int.Parse(code[12].ToString()) * 3; int sum = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10] + a[11] + a[12]; int check = (10 - (sum % 10)) % 10; // evaluate check digit int last = int.Parse(code[13].ToString()); return check == last; } 

GS1 US在PDF文档中发布了GTIN的校验位计算算法(删除了不断变化的链接)。

以下代码使用linq检查GTIN条形码的最后一位数:GTIN-8,GTIN-12(UPC),GTIN-13(EAN)和GTIN-14(ITF-14)。

 private static Regex _gtinRegex = new System.Text.RegularExpressions.Regex("^(\\d{8}|\\d{12,14})$"); public static bool IsValidGtin(string code) { if (!(_gtinRegex.IsMatch(code))) return false; // check if all digits and with 8, 12, 13 or 14 digits code = code.PadLeft(14, '0'); // stuff zeros at start to garantee 14 digits int[] mult = Enumerable.Range(0, 13).Select(i => ((int)(code[i] - '0')) * ((i % 2 == 0) ? 3 : 1)).ToArray(); // STEP 1: without check digit, "Multiply value of each position" by 3 or 1 int sum = mult.Sum(); // STEP 2: "Add results together to create sum" return (10 - (sum % 10)) % 10 == int.Parse(code[13].ToString()); // STEP 3 Equivalent to "Subtract the sum from the nearest equal or higher multiple of ten = CHECK DIGIT" } 

上面的解决方案计算校验位并将其与给定的数字进行比较,忽略了它被设计为以更简单的方式validation的事实。

  1. 将所有数字( 包括校验位 )乘以3或1和求和。
  2. 检查总和是否是10的倍数

根据卢西亚诺的回答:

 private static Regex _gtinRegex = new Regex("^(\\d{8}|\\d{12,14})$"); public static bool IsValidGtin(string code) { if (!(_gtinRegex.IsMatch(code))) return false; code = code.PadLeft(14, '0'); int sum = code.Select((c,i) => (c - '0') * ((i % 2 == 0) ? 3 : 1)).Sum(); return (sum % 10) == 0; } 

可变长度的EAN

  public static bool IsValidEan13(string eanBarcode) { return IsValidEan(eanBarcode, 13); } public static bool IsValidEan12(string eanBarcode) { return IsValidEan(eanBarcode, 12); } public static bool IsValidEan14(string eanBarcode) { return IsValidEan(eanBarcode, 14); } public static bool IsValidEan8(string eanBarcode) { return IsValidEan(eanBarcode, 8); } private static bool IsValidEan(string eanBarcode, int length) { if (eanBarcode.Length != length) return false; var allDigits = eanBarcode.Select(c => int.Parse(c.ToString(CultureInfo.InvariantCulture))).ToArray(); var s = length%2 == 0 ? 3 : 1; var s2 = s == 3 ? 1 : 3; return allDigits.Last() == (10 - (allDigits.Take(length-1).Select((c, ci) => c*(ci%2 == 0 ? s : s2)).Sum()%10))%10; } [Test] [TestCaseSource("Ean_13_TestCases")] public void Check_Ean13_Is_Valid(string ean, bool isValid) { BlinkBuilder.IsValidEan13(ean).Should().Be(isValid); } private static IEnumerable Ean_13_TestCases() { yield return new object[] { "9781118143308", true }; yield return new object[] { "978111814330", false }; yield return new object[] { "97811181433081", false }; yield return new object[] { "5017188883399", true }; } [Test] [TestCaseSource("Ean_8_TestCases")] public void Check_Ean8_Is_Valid(string ean, bool isValid) { BlinkBuilder.IsValidEan8(ean).Should().Be(isValid); } private static IEnumerable Ean_8_TestCases() { yield return new object[] { "12345670", true }; yield return new object[] { "12345679", false }; yield return new object[] { "55432214", true }; yield return new object[] { "55432213", false }; yield return new object[] { "55432215", false }; } 

编辑

我正在构建此代码的项目现已启动并运行 – 它是全面的条形码数据库和工具集的一部分 – 并且包括批量条形码validation器(非注册用户批量100个,注册10,000个) – https:// blinked.in/tools/validator

 ///  /// Validates a GTIN (UPC/EAN) using the terminating check digit ///  /// the string representing the GTIN /// True if the check digit matches, false if the code is not /// parsable as a GTIN or the check digit does not match public static bool IsValidGtin(string code) { if (string.IsNullOrWhiteSpace(code)) return false; if (code.Length != 8 && code.Length != 12 && code.Length != 13 && code.Length != 14) // wrong number of digits return false; int sum = 0; for (int i = 0; i < code.Length - 1 /* do not include check char */; i++) { if (!char.IsNumber(code[i])) return false; var cchari = (int)char.GetNumericValue(code[i]); // even (from the right) characters get multiplied by 3 // add the length to align right if ((code.Length + i) % 2 == 0) sum += cchari * 3; else sum += cchari; } // validate check char char checkChar = code[code.Length - 1]; if (!char.IsNumber(checkChar)) return false; int checkChari = (int)char.GetNumericValue(checkChar); return checkChari == (10 - (sum % 10)) % 10; } 

测试用例:

  [TestMethod()] public void IsValidGtinTest_Valid() { string[] valid = new[] { "085126880552", "0085126880552", "00085126880552", "0786936226355", "0719852136552" }; foreach (var upc in valid) Assert.IsTrue(IdentifierUtilities.IsValidGtin(upc), upc); } [TestMethod()] public void IsValidGtinTest_Invalid() { string[] invalid = new[] { "0058126880552", "58126880552", "0786936223655", "0719853136552", "", "00", null, "123456789123456789123456789", "1111111111111" }; foreach (var upc in invalid) Assert.IsFalse(IdentifierUtilities.IsValidGtin(upc), upc); } 
  private bool ValidateCheckDigit() { Int32 _num = 0; Int32 _checkdigit = 0; for (int i = 0; i < CurrentUpcInfo.UpcCode.Length; i++) { if (i % 2 == 0) { _num += (3 * Convert.ToInt32(CurrentUpcInfo.UpcCode.Substring(i, 1))); } else { _num += Convert.ToInt32(CurrentUpcInfo.UpcCode.Substring(i, 1)); } } _num = Math.Abs(_num) + 10; // in case num is a zero _checkdigit = (10 - (_num % 10)) % 10; if (Convert.ToInt32(CurrentUpcInfo.Checkdigit) == _checkdigit) return true; return false; } 

我遇到了类似的问题,谷歌把我带到了这个页面。 我需要为标签生成程序计算大量条形码的校验位。 我首先从上面的Luciano Carvalho的答案开始,但我有点好奇将字符串转换为字符串到int。 我怀疑我可能会稍微改善一下性能。

请注意,此function之外的validation正在进行。 由于我生成了大量的条形码,因此该function的构建更加快速。

 int CalculateCheckDigit(ulong label) { int sum = 0; bool isEven=true; while(label>0) { if(isEven) sum += (int)(label % 10) * 3; else sum += (int)(label % 10) * 1; isEven = !isEven; label /= 10; } return (10 - (sum % 10)) % 10; } 

我知道问题出在.net / C#的上下文中。 不过我登陆这个页面寻求回答同一个问题,但是在Groovy环境中。

由于我实际上成功地使用了本页面上的信息来回答我自己的问题,我想我会分享结果。
特别是AlexDev,Zack Peterson和Mitch的答案对我很有帮助。

 /* Check digit calculation is based on modulus 10 with digits in an odd position (from right to left) being weighted 1 and even position digits being weighted 3. For further information on EAN-13 see: Wikipedia - European Article Number: http://en.wikipedia.org/wiki/International_Article_Number_%28EAN%29 Implementation based on http://stackoverflow.com/questions/10143547/how-do-i-validate-a-upc-or-ean-code Tests can be found there too */ boolean isValidEan(String code){ returnValue = false if (code ==~ /\d{8}|\d{12,14}/){ //Matches if String code contains 8, 12, 13 or 14 digits assert [8,12,13,14].contains(code.size()) code = code.padLeft(14, '0') assert code.size() == 14 int sum = 0 code.eachWithIndex{ c, i -> sum += c.toInteger() * ((i % 2 == 0) ? 3 : 1) } returnValue = sum % 10 == 0 } return returnValue } 

def check_digit():

  users_gtin=raw_input("enter first seven digits of gtin ") gtin_seven_digits=unicode(users_gtin) if len(gtin_seven_digits) == 7 and gtin_seven_digits.isnumeric(): ck = ((((int(gtin_seven_digits[0])) + (int(gtin_seven_digits[2])) + (int(gtin_seven_digits[4])) + (int(gtin_seven_digits[6])))*3) + ((int(gtin_seven_digits[1])) + (int(gtin_seven_digits[3])) + (int(gtin_seven_digits[5])))) %10 final_ck = 10-ck if final_ck == 10: final_ck=0 print "Is your check digit",final_ck,"?" else: print "Is your check digit",final_ck,"?" else: print "please try typing an seven digit number" check_digit() choice=raw_input("enter (a) to restart or press anything other than the letter a to end this program <<<< ").upper() if choice == "A": check_digit() 

检查数字()

可能不是最有效但希望它有帮助..

我找到了这个Nuget包: https ://www.nuget.org/packages/ProductCodeValidator/

github中的代码是: https : //github.com/ThomasPe/ProductCodeValidator 。

以下是如何使用它:

 using ProductCodeValidator; bool IsValidEAN(string EAN) { return EanValidator.IsValidEan(testEan)); } 
 private void button1_Click(object sender, EventArgs e) { string code = textBox1.Text; string sBarcode = string.Empty; sBarcode = IsValidGtin(code); lblBarCode.Text = sBarcode; } public static string IsValidGtin(string code) { //if (code != (new Regex("[^0-9]")).Replace(code, "")) //{ // // is not numeric // return false; //} // pad with zeros to lengthen to 14 digits switch (code.Length) { case 2: code = code + "000000000"; break; case 3: code = code + "00000000"; break; case 4: code = code + "0000000"; break; case 5: code = code + "000000"; break; case 6: code = code + "00000"; break; case 7: code = code + "0000"; break; case 8: code = code + "000"; break; case 9: code = code + "00"; break; case 10: code = code + "0"; break; case 11: break; case 12: code = code.Substring(0, 11); break; //default: // wrong number of digits // return false; } // calculate check digit int[] a = new int[12]; a[0] = int.Parse(code[0].ToString()) * 3; a[1] = int.Parse(code[1].ToString()); a[2] = int.Parse(code[2].ToString()) * 3; a[3] = int.Parse(code[3].ToString()); a[4] = int.Parse(code[4].ToString()) * 3; a[5] = int.Parse(code[5].ToString()); a[6] = int.Parse(code[6].ToString()) * 3; a[7] = int.Parse(code[7].ToString()); a[8] = int.Parse(code[8].ToString()) * 3; a[9] = int.Parse(code[9].ToString()); a[10] = int.Parse(code[10].ToString()) * 3; //a[11] = int.Parse(code[11].ToString()); //a[12] = int.Parse(code[12].ToString()) * 3; int sum = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10]; string check = Convert.ToString((10 - (sum % 10))); // evaluate check digit // int last = int.Parse(code[13].ToString()); // return check == last; code = code + check; return code; }