diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/GS1Parser/GS1Parser.sln b/GS1Parser/GS1Parser.sln
new file mode 100644
index 0000000..23a4a5d
--- /dev/null
+++ b/GS1Parser/GS1Parser.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GS1Parser", "GS1Parser\GS1Parser.csproj", "{0C089F3C-680F-4AD0-8070-715C4A4C3850}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0C089F3C-680F-4AD0-8070-715C4A4C3850}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0C089F3C-680F-4AD0-8070-715C4A4C3850}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0C089F3C-680F-4AD0-8070-715C4A4C3850}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0C089F3C-680F-4AD0-8070-715C4A4C3850}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/GS1Parser/GS1Parser/GS1.cs b/GS1Parser/GS1Parser/GS1.cs
new file mode 100644
index 0000000..ff2d6c7
--- /dev/null
+++ b/GS1Parser/GS1Parser/GS1.cs
@@ -0,0 +1,302 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GS1Parser
+{
+ public static class GS1
+ {
+ public enum DataType
+ {
+ Numeric,
+ Alphanumeric
+ }
+
+ ///
+ /// Information Class for an Application Identifier (AI)
+ ///
+ public class AII
+ {
+ public string AI { get; set; }
+ public string Description { get; set; }
+ public int LengthOfAI { get; set; }
+ public DataType DataDescription { get; set; }
+ public int LengthOfData { get; set; }
+ public bool FNC1 { get; set; }
+
+ public AII(string AI, string Description, int LengthOfAI, DataType DataDescription, int LengthOfData, bool FNC1)
+ {
+ this.AI = AI;
+ this.Description = Description;
+ this.LengthOfAI = LengthOfAI;
+ this.DataDescription = DataDescription;
+ this.LengthOfData = LengthOfData;
+ this.FNC1 = FNC1;
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0} [{1}]", AI, Description);
+ }
+ }
+
+ private static SortedDictionary aiiDict = new SortedDictionary();
+ private static string[] aiis;
+ private static int minLengthOfAI = 1;
+ private static int maxLengthOfAI = 4;
+ private static char groutSeperator = (char)29;
+ private static string ean128StartCode = "]C1";
+ private static bool hasCheckSum = true;
+
+ public static bool HasCheckSum
+ {
+ get { return EAN128Parser.hasCheckSum; }
+ set { EAN128Parser.hasCheckSum = value; }
+ }
+
+ public static char GroutSeperator
+ {
+ get { return EAN128Parser.groutSeperator; }
+ set { EAN128Parser.groutSeperator = value; }
+ }
+
+ public static string EAN128StartCode
+ {
+ get { return EAN128Parser.ean128StartCode; }
+ set { EAN128Parser.ean128StartCode = value; }
+ }
+
+ static EAN128Parser()
+ {
+ Add("00", "SerialShippingContainerCode", 2, DataType.Numeric, 18, false);
+ Add("01", "EAN-NumberOfTradingUnit", 2, DataType.Numeric, 14, false);
+ Add("02", "EAN-NumberOfTheWaresInTheShippingUnit", 2, DataType.Numeric, 14, false);
+ Add("10", "Charge_Number", 2, DataType.Alphanumeric, 20, true);
+ Add("11", "ProducerDate_JJMMDD", 2, DataType.Numeric, 6, false);
+ Add("12", "DueDate_JJMMDD", 2, DataType.Numeric, 6, false);
+ Add("13", "PackingDate_JJMMDD", 2, DataType.Numeric, 6, false);
+ Add("15", "MinimumDurabilityDate_JJMMDD", 2, DataType.Numeric, 6, false);
+ Add("17", "ExpiryDate_JJMMDD", 2, DataType.Numeric, 6, false);
+ Add("20", "ProductModel", 2, DataType.Numeric, 2, false);
+ Add("21", "SerialNumber", 2, DataType.Alphanumeric, 20, true);
+ Add("22", "HIBCCNumber", 2, DataType.Alphanumeric, 29, false);
+ Add("240", "PruductIdentificationOfProducer", 3, DataType.Alphanumeric, 30, true);
+ Add("241", "CustomerPartsNumber", 3, DataType.Alphanumeric, 30, true);
+ Add("250", "SerialNumberOfAIntegratedModule", 3, DataType.Alphanumeric, 30, true);
+ Add("251", "ReferenceToTheBasisUnit", 3, DataType.Alphanumeric, 30, true);
+ Add("252", "GlobalIdentifierSerialisedForTrade", 3, DataType.Numeric, 2, false);
+ Add("30", "AmountInParts", 2, DataType.Numeric, 8, true);
+ Add("310d", "NetWeight_Kilogram", 4, DataType.Numeric, 6, false);
+ Add("311d", "Length_Meter", 4, DataType.Numeric, 6, false);
+ Add("312d", "Width_Meter", 4, DataType.Numeric, 6, false);
+ Add("313d", "Heigth_Meter", 4, DataType.Numeric, 6, false);
+ Add("314d", "Surface_SquareMeter", 4, DataType.Numeric, 6, false);
+ Add("315d", "NetVolume_Liters", 4, DataType.Numeric, 6, false);
+ Add("316d", "NetVolume_CubicMeters", 4, DataType.Numeric, 6, false);
+ Add("320d", "NetWeight_Pounds", 4, DataType.Numeric, 6, false);
+ Add("321d", "Length_Inches", 4, DataType.Numeric, 6, false);
+ Add("322d", "Length_Feet", 4, DataType.Numeric, 6, false);
+ Add("323d", "Length_Yards", 4, DataType.Numeric, 6, false);
+ Add("324d", "Width_Inches", 4, DataType.Numeric, 6, false);
+ Add("325d", "Width_Feed", 4, DataType.Numeric, 6, false);
+ Add("326d", "Width_Yards", 4, DataType.Numeric, 6, false);
+ Add("327d", "Heigth_Inches", 4, DataType.Numeric, 6, false);
+ Add("328d", "Heigth_Feed", 4, DataType.Numeric, 6, false);
+ Add("329d", "Heigth_Yards", 4, DataType.Numeric, 6, false);
+ Add("330d", "GrossWeight_Kilogram", 4, DataType.Numeric, 6, false);
+ Add("331d", "Length_Meter", 4, DataType.Numeric, 6, false);
+ Add("332d", "Width_Meter", 4, DataType.Numeric, 6, false);
+ Add("333d", "Heigth_Meter", 4, DataType.Numeric, 6, false);
+ Add("334d", "Surface_SquareMeter", 4, DataType.Numeric, 6, false);
+ Add("335d", "GrossVolume_Liters", 4, DataType.Numeric, 6, false);
+ Add("336d", "GrossVolume_CubicMeters", 4, DataType.Numeric, 6, false);
+ Add("337d", "KilogramPerSquareMeter", 4, DataType.Numeric, 6, false);
+ Add("340d", "GrossWeight_Pounds", 4, DataType.Numeric, 6, false);
+ Add("341d", "Length_Inches", 4, DataType.Numeric, 6, false);
+ Add("342d", "Length_Feet", 4, DataType.Numeric, 6, false);
+ Add("343d", "Length_Yards", 4, DataType.Numeric, 6, false);
+ Add("344d", "Width_Inches", 4, DataType.Numeric, 6, false);
+ Add("345d", "Width_Feed", 4, DataType.Numeric, 6, false);
+ Add("346d", "Width_Yards", 4, DataType.Numeric, 6, false);
+ Add("347d", "Heigth_Inches", 4, DataType.Numeric, 6, false);
+ Add("348d", "Heigth_Feed", 4, DataType.Numeric, 6, false);
+ Add("349d", "Heigth_Yards", 4, DataType.Numeric, 6, false);
+ Add("350d", "Surface_SquareInches", 4, DataType.Numeric, 6, false);
+ Add("351d", "Surface_SquareFeet", 4, DataType.Numeric, 6, false);
+ Add("352d", "Surface_SquareYards", 4, DataType.Numeric, 6, false);
+ Add("353d", "Surface_SquareInches", 4, DataType.Numeric, 6, false);
+ Add("354d", "Surface_SquareFeed", 4, DataType.Numeric, 6, false);
+ Add("355d", "Surface_SquareYards", 4, DataType.Numeric, 6, false);
+ Add("356d", "NetWeight_TroyOunces", 4, DataType.Numeric, 6, false);
+ Add("357d", "NetVolume_Ounces", 4, DataType.Numeric, 6, false);
+ Add("360d", "NetVolume_Quarts", 4, DataType.Numeric, 6, false);
+ Add("361d", "NetVolume_Gallonen", 4, DataType.Numeric, 6, false);
+ Add("362d", "GrossVolume_Quarts", 4, DataType.Numeric, 6, false);
+ Add("363d", "GrossVolume_Gallonen", 4, DataType.Numeric, 6, false);
+ Add("364d", "NetVolume_CubicInches", 4, DataType.Numeric, 6, false);
+ Add("365d", "NetVolume_CubicFeet", 4, DataType.Numeric, 6, false);
+ Add("366d", "NetVolume_CubicYards", 4, DataType.Numeric, 6, false);
+ Add("367d", "GrossVolume_CubicInches", 4, DataType.Numeric, 6, false);
+ Add("368d", "GrossVolume_CubicFeet", 4, DataType.Numeric, 6, false);
+ Add("369d", "GrossVolume_CubicYards", 4, DataType.Numeric, 6, false);
+ Add("37", "QuantityInParts", 2, DataType.Numeric, 8, true);
+ Add("390d", "AmountDue_DefinedValutaBand", 4, DataType.Numeric, 15, true);
+ Add("391d", "AmountDue_WithISOValutaCode", 4, DataType.Numeric, 18, true);
+ Add("392d", "BePayingAmount_DefinedValutaBand", 4, DataType.Numeric, 15, true);
+ Add("393d", "BePayingAmount_WithISOValutaCode", 4, DataType.Numeric, 18, true);
+ Add("400", "JobNumberOfGoodsRecipient", 3, DataType.Alphanumeric, 30, true);
+ Add("401", "ShippingNumber", 3, DataType.Alphanumeric, 30, true);
+ Add("402", "DeliveryNumber", 3, DataType.Numeric, 17, false);
+ Add("403", "RoutingCode", 3, DataType.Alphanumeric, 30, true);
+ Add("410", "EAN_UCC_GlobalLocationNumber(GLN)_GoodsRecipient", 3, DataType.Numeric, 13, false);
+ Add("411", "EAN_UCC_GlobalLocationNumber(GLN)_InvoiceRecipient", 3, DataType.Numeric, 13, false);
+ Add("412", "EAN_UCC_GlobalLocationNumber(GLN)_Distributor", 3, DataType.Numeric, 13, false);
+ Add("413", "EAN_UCC_GlobalLocationNumber(GLN)_FinalRecipient", 3, DataType.Numeric, 13, false);
+ Add("414", "EAN_UCC_GlobalLocationNumber(GLN)_PhysicalLocation", 3, DataType.Numeric, 13, false);
+ Add("415", "EAN_UCC_GlobalLocationNumber(GLN)_ToBilligParticipant", 3, DataType.Numeric, 13, false);
+ Add("420", "ZipCodeOfRecipient_withoutCountryCode", 3, DataType.Alphanumeric, 20, true);
+ Add("421", "ZipCodeOfRecipient_withCountryCode", 3, DataType.Alphanumeric, 12, true);
+ Add("422", "BasisCountryOfTheWares_ISO3166Format", 3, DataType.Numeric, 3, false);
+ Add("7001", "Nato Stock Number", 4, DataType.Numeric, 13, false);
+ Add("8001", "RolesProducts", 4, DataType.Numeric, 14, false);
+ Add("8002", "SerialNumberForMobilePhones", 4, DataType.Alphanumeric, 20, true);
+ Add("8003", "GlobalReturnableAssetIdentifier", 4, DataType.Alphanumeric, 34, true);
+ Add("8004", "GlobalIndividualAssetIdentifier", 4, DataType.Numeric, 30, true);
+ Add("8005", "SalesPricePerUnit", 4, DataType.Numeric, 6, false);
+ Add("8006", "IdentifikationOfAProductComponent", 4, DataType.Numeric, 18, false);
+ Add("8007", "IBAN", 4, DataType.Alphanumeric, 30, true);
+ Add("8008", "DataAndTimeOfManufacturing", 4, DataType.Numeric, 12, true);
+ Add("8018", "GlobalServiceRelationNumber", 4, DataType.Numeric, 18, false);
+ Add("8020", "NumberBillCoverNumber", 4, DataType.Alphanumeric, 25, false);
+ Add("8100", "CouponExtendedCode_NSC_offerCcode", 4, DataType.Numeric, 10, false);
+ Add("8101", "CouponExtendedCode_NSC_offerCcode_EndOfOfferCode", 4, DataType.Numeric, 14, false);
+ Add("8102", "CouponExtendedCode_NSC", 4, DataType.Numeric, 6, false);
+ Add("90", "InformationForBilateralCoordinatedApplications", 2, DataType.Alphanumeric, 30, true);
+ //Add("91", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("92", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("93", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("94", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("95", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("96", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("97", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("98", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ //Add("99", "Company specific", 2, DataType.Alphanumeric, 30, true);
+ aiis = aiiDict.Keys.ToArray();
+ minLengthOfAI = aiiDict.Values.Min(el => el.LengthOfAI);
+ maxLengthOfAI = aiiDict.Values.Max(el => el.LengthOfAI);
+
+ }
+ ///
+ /// Add an Application Identifier (AI)
+ ///
+ /// Number of the AI
+ ///
+ ///
+ /// The type of the content
+ /// The max lenght of the content
+ /// Support a group seperator
+ public static void Add(string AI, string Description, int LengthOfAI, DataType DataDescription, int LengthOfData, bool FNC1)
+ {
+ aiiDict[AI] = new AII(AI, Description, LengthOfAI, DataDescription, LengthOfData, FNC1);
+ }
+
+ ///
+ /// Parse the ean128 code
+ ///
+ /// The raw scanner data
+ /// If an exception will be thrown if an AI cannot be found
+ /// The different parts of the ean128 code
+ public static Dictionary Parse(string data, bool throwException = false)
+ {
+ // cut off the EAN128 start code
+ if (data.StartsWith(EAN128StartCode))
+ data = data.Substring(EAN128StartCode.Length);
+ // cut off the check sum
+ if (HasCheckSum)
+ data = data.Substring(0, data.Length - 2);
+
+ Dictionary result = new Dictionary();
+ int index = 0;
+ // walkk through the EAN128 code
+ while (index < data.Length)
+ {
+ // try to get the AI at the current position
+ var ai = GetAI(data, ref index);
+ if (ai == null)
+ {
+ if (throwException)
+ throw new InvalidOperationException("AI not found");
+ return result;
+ }
+ // get the data to the current AI
+ string code = GetCode(data, ai, ref index);
+ result[ai] = code;
+ }
+
+ return result;
+ }
+
+ ///
+ /// Try to get the AI at the current position
+ ///
+ /// The row data from the scanner
+ /// The refrence of the current position
+ /// Sets if the last character of the AI should replaced with a placehoder ("d")
+ /// The current AI or null if no match was found
+ private static AII GetAI(string data, ref int index, bool usePlaceHolder = false)
+ {
+ AII result = null;
+ // Step through the different lenghts of the AIs
+ for (int i = minLengthOfAI; i <= maxLengthOfAI; i++)
+ {
+ // get the AI sub string
+ string ai = data.Substring(index, i);
+ if (usePlaceHolder)
+ ai = ai.Remove(ai.Length - 1) + "d";
+ // try to get the ai from the dictionary
+ if (aiiDict.TryGetValue(ai, out result))
+ {
+ // Shift the index to the next
+ index += i;
+ return result;
+ }
+ // if no AI found, try it with the next lenght
+ }
+ // if no AI found here, than try it with placeholders. Assumed that is the first sep where usePlaceHolder is false
+ if (!usePlaceHolder)
+ result = GetAI(data, ref index, true);
+ return result;
+ }
+
+ ///
+ /// Get the current code to the AI
+ ///
+ /// The row data from the scanner
+ /// The current AI
+ /// The refrence of the current position
+ /// the data to the current AI
+ private static string GetCode(string data, AII ai, ref int index)
+ {
+ // get the max lenght to read.
+ int lenghtToRead = Math.Min(ai.LengthOfData, data.Length - index);
+ // get the data of the current AI
+ string result = data.Substring(index, lenghtToRead);
+ // check if the AI support a group seperator
+ if (ai.FNC1)
+ {
+ // try to find the index of the group seperator
+ int indexOfGroupTermination = result.IndexOf(GroutSeperator);
+ if (indexOfGroupTermination >= 0)
+ lenghtToRead = indexOfGroupTermination + 1;
+ // get the data of the current AI till the gorup seperator
+ result = data.Substring(index, lenghtToRead);
+ }
+
+ // Shift the index to the next
+ index += lenghtToRead;
+ return result;
+ }
+ }
+}
diff --git a/GS1Parser/GS1Parser/GS1Parser.csproj b/GS1Parser/GS1Parser/GS1Parser.csproj
new file mode 100644
index 0000000..89321e0
--- /dev/null
+++ b/GS1Parser/GS1Parser/GS1Parser.csproj
@@ -0,0 +1,53 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {0C089F3C-680F-4AD0-8070-715C4A4C3850}
+ Library
+ Properties
+ GS1Parser
+ GS1Parser
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GS1Parser/GS1Parser/Properties/AssemblyInfo.cs b/GS1Parser/GS1Parser/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e878802
--- /dev/null
+++ b/GS1Parser/GS1Parser/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GS1Parser")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GS1Parser")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d527a178-b78f-4ca1-97f4-df88ccc2efff")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/README.md b/README.md
index f55872e..e9e7e16 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,8 @@
# GS1Parser
A GS1 Parser for C#
+
+Input a string, get a dictionary of GS1 Application Identifiers.
+
+Originally developed from a Stackoverflow Answer
+
+http://stackoverflow.com/questions/9721718/ean128-or-gs1-128-decode-c-sharp/28854802#28854802
\ No newline at end of file