带你人工识别C#开源库BarcodeLib生成的一维码Code128

我们是做HIS系统开发的,前段时间发现某些处方的一维码出现无法识别的情况。看了一下一维码生成的逻辑,使用到了BarcodeLib库,经过反复确认,我们程序是没有问题的。后面不得不反编译看一下BarcodeLib生成一维码的逻辑。最后调整一维码的宽度解决了问题。而且发现它的编码和通信领域的编码思想有神奇的相似之处。编码格式类型:开始位+数据位+检查校验位+STOP停止位+11。总的来说是解密和编码都是查表法,如要把数字69进行编码,通过查表可以知道编码的结果为:10110010000。 解密就是逆过程,如知道编码为10110010000,通过查表,也可以知道编码前的数字为69

这里简单介绍一下BarcodeLib库Code128一维码的编码过程:

1   先把数字如:6986081进行编码,两个数字作为一组进行编码,这里数字69一组,86一组,08一组,剩下一个1就比较特别,源码看得不是很懂,有特殊的规则进行编码

2  把两位数字通过查表法进行编码,编码为11位的0或1数字。如数字69编码为10110010000

3  通过C#的绘图类Graphics的画线方法.DrawLine进行绘制线,如要绘制10110010000编码,碰到1就纵向绘制一定宽度的直线,碰到0就不绘制直线。

下面我们一起来分析一下这个一维码:

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第1张图片

先告知一下这个一维码的值为:6986081

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第2张图片

通过上图的分析,上图的编码可以编码为:

1101001110010110010000111101001001000110010011101011110
10011100110100010001101100011101011

按照11位进行分组整理后如下:

11010011100
10110010000
11110100100 
10001100100
11101011110
10011100110
10001000110 
11000111010 
11

通过编码11010011100查找本文后面的编码表得到的数值为START_C

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第3张图片

通过编码10110010000查找本文后面的编码表得到的数值为69

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第4张图片

通过编码10001100100查找本文后面的编码表得到的数值为08

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第5张图片

通过编码11101011110查找本文后面的编码表得到的数值为CODE_A

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第6张图片

通过编码10011100110 查找本文后面的编码表得到的数值为17,但前面有一个CODE_A,应该编码为1

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第7张图片

通过编码10001000110查找本文后面的编码表得到的数值为C,则为检查校验位

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第8张图片

通过编码11000111010查找本文后面的编码表得到的数值为STOP,则为停止位

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第9张图片

最后两位11应该也是校验位吧。

最后汇总如下:

11010011100    START_C 开始  
10110010000    69
11110100100    86
10001100100    08
11101011110    CODE_A
10011100110    这个是编1而不是17
10001000110    检查校验位
11000111010    STOP停止位
11

最后一维码的解码结果为:6986081

补充说明:

BarcodeLib库Code128编码表如下,偷懒一点,就直接贴源码了


private void init_Code128()
{
			this.C128_Code.CaseSensitive = true;
			this.C128_Code.Columns.Add("Value", typeof(string));
			this.C128_Code.Columns.Add("A", typeof(string));
			this.C128_Code.Columns.Add("B", typeof(string));
			this.C128_Code.Columns.Add("C", typeof(string));
			this.C128_Code.Columns.Add("Encoding", typeof(string));
			this.C128_Code.Rows.Add(new object[]
			{
				"0",
				" ",
				" ",
				"00",
				"11011001100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"1",
				"!",
				"!",
				"01",
				"11001101100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"2",
				"\"",
				"\"",
				"02",
				"11001100110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"3",
				"#",
				"#",
				"03",
				"10010011000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"4",
				"$",
				"$",
				"04",
				"10010001100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"5",
				"%",
				"%",
				"05",
				"10001001100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"6",
				"&",
				"&",
				"06",
				"10011001000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"7",
				"'",
				"'",
				"07",
				"10011000100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"8",
				"(",
				"(",
				"08",
				"10001100100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"9",
				")",
				")",
				"09",
				"11001001000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"10",
				"*",
				"*",
				"10",
				"11001000100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"11",
				"+",
				"+",
				"11",
				"11000100100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"12",
				",",
				",",
				"12",
				"10110011100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"13",
				"-",
				"-",
				"13",
				"10011011100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"14",
				".",
				".",
				"14",
				"10011001110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"15",
				"/",
				"/",
				"15",
				"10111001100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"16",
				"0",
				"0",
				"16",
				"10011101100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"17",
				"1",
				"1",
				"17",
				"10011100110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"18",
				"2",
				"2",
				"18",
				"11001110010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"19",
				"3",
				"3",
				"19",
				"11001011100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"20",
				"4",
				"4",
				"20",
				"11001001110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"21",
				"5",
				"5",
				"21",
				"11011100100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"22",
				"6",
				"6",
				"22",
				"11001110100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"23",
				"7",
				"7",
				"23",
				"11101101110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"24",
				"8",
				"8",
				"24",
				"11101001100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"25",
				"9",
				"9",
				"25",
				"11100101100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"26",
				":",
				":",
				"26",
				"11100100110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"27",
				";",
				";",
				"27",
				"11101100100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"28",
				"<",
				"<",
				"28",
				"11100110100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"29",
				"=",
				"=",
				"29",
				"11100110010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"30",
				">",
				">",
				"30",
				"11011011000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"31",
				"?",
				"?",
				"31",
				"11011000110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"32",
				"@",
				"@",
				"32",
				"11000110110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"33",
				"A",
				"A",
				"33",
				"10100011000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"34",
				"B",
				"B",
				"34",
				"10001011000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"35",
				"C",
				"C",
				"35",
				"10001000110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"36",
				"D",
				"D",
				"36",
				"10110001000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"37",
				"E",
				"E",
				"37",
				"10001101000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"38",
				"F",
				"F",
				"38",
				"10001100010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"39",
				"G",
				"G",
				"39",
				"11010001000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"40",
				"H",
				"H",
				"40",
				"11000101000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"41",
				"I",
				"I",
				"41",
				"11000100010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"42",
				"J",
				"J",
				"42",
				"10110111000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"43",
				"K",
				"K",
				"43",
				"10110001110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"44",
				"L",
				"L",
				"44",
				"10001101110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"45",
				"M",
				"M",
				"45",
				"10111011000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"46",
				"N",
				"N",
				"46",
				"10111000110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"47",
				"O",
				"O",
				"47",
				"10001110110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"48",
				"P",
				"P",
				"48",
				"11101110110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"49",
				"Q",
				"Q",
				"49",
				"11010001110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"50",
				"R",
				"R",
				"50",
				"11000101110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"51",
				"S",
				"S",
				"51",
				"11011101000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"52",
				"T",
				"T",
				"52",
				"11011100010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"53",
				"U",
				"U",
				"53",
				"11011101110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"54",
				"V",
				"V",
				"54",
				"11101011000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"55",
				"W",
				"W",
				"55",
				"11101000110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"56",
				"X",
				"X",
				"56",
				"11100010110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"57",
				"Y",
				"Y",
				"57",
				"11101101000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"58",
				"Z",
				"Z",
				"58",
				"11101100010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"59",
				"[",
				"[",
				"59",
				"11100011010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"60",
				"\\",
				"\\",
				"60",
				"11101111010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"61",
				"]",
				"]",
				"61",
				"11001000010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"62",
				"^",
				"^",
				"62",
				"11110001010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"63",
				"_",
				"_",
				"63",
				"10100110000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"64",
				"\0",
				"`",
				"64",
				"10100001100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"65",
				Convert.ToChar(1).ToString(),
				"a",
				"65",
				"10010110000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"66",
				Convert.ToChar(2).ToString(),
				"b",
				"66",
				"10010000110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"67",
				Convert.ToChar(3).ToString(),
				"c",
				"67",
				"10000101100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"68",
				Convert.ToChar(4).ToString(),
				"d",
				"68",
				"10000100110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"69",
				Convert.ToChar(5).ToString(),
				"e",
				"69",
				"10110010000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"70",
				Convert.ToChar(6).ToString(),
				"f",
				"70",
				"10110000100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"71",
				Convert.ToChar(7).ToString(),
				"g",
				"71",
				"10011010000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"72",
				Convert.ToChar(8).ToString(),
				"h",
				"72",
				"10011000010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"73",
				Convert.ToChar(9).ToString(),
				"i",
				"73",
				"10000110100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"74",
				Convert.ToChar(10).ToString(),
				"j",
				"74",
				"10000110010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"75",
				Convert.ToChar(11).ToString(),
				"k",
				"75",
				"11000010010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"76",
				Convert.ToChar(12).ToString(),
				"l",
				"76",
				"11001010000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"77",
				Convert.ToChar(13).ToString(),
				"m",
				"77",
				"11110111010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"78",
				Convert.ToChar(14).ToString(),
				"n",
				"78",
				"11000010100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"79",
				Convert.ToChar(15).ToString(),
				"o",
				"79",
				"10001111010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"80",
				Convert.ToChar(16).ToString(),
				"p",
				"80",
				"10100111100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"81",
				Convert.ToChar(17).ToString(),
				"q",
				"81",
				"10010111100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"82",
				Convert.ToChar(18).ToString(),
				"r",
				"82",
				"10010011110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"83",
				Convert.ToChar(19).ToString(),
				"s",
				"83",
				"10111100100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"84",
				Convert.ToChar(20).ToString(),
				"t",
				"84",
				"10011110100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"85",
				Convert.ToChar(21).ToString(),
				"u",
				"85",
				"10011110010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"86",
				Convert.ToChar(22).ToString(),
				"v",
				"86",
				"11110100100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"87",
				Convert.ToChar(23).ToString(),
				"w",
				"87",
				"11110010100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"88",
				Convert.ToChar(24).ToString(),
				"x",
				"88",
				"11110010010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"89",
				Convert.ToChar(25).ToString(),
				"y",
				"89",
				"11011011110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"90",
				Convert.ToChar(26).ToString(),
				"z",
				"90",
				"11011110110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"91",
				Convert.ToChar(27).ToString(),
				"{",
				"91",
				"11110110110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"92",
				Convert.ToChar(28).ToString(),
				"|",
				"92",
				"10101111000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"93",
				Convert.ToChar(29).ToString(),
				"}",
				"93",
				"10100011110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"94",
				Convert.ToChar(30).ToString(),
				"~",
				"94",
				"10001011110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"95",
				Convert.ToChar(31).ToString(),
				Convert.ToChar(127).ToString(),
				"95",
				"10111101000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"96",
				Convert.ToChar(202).ToString(),
				Convert.ToChar(202).ToString(),
				"96",
				"10111100010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"97",
				Convert.ToChar(201).ToString(),
				Convert.ToChar(201).ToString(),
				"97",
				"11110101000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"98",
				"SHIFT",
				"SHIFT",
				"98",
				"11110100010"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"99",
				"CODE_C",
				"CODE_C",
				"99",
				"10111011110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"100",
				"CODE_B",
				Convert.ToChar(203).ToString(),
				"CODE_B",
				"10111101110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"101",
				Convert.ToChar(203).ToString(),
				"CODE_A",
				"CODE_A",
				"11101011110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"102",
				Convert.ToChar(200).ToString(),
				Convert.ToChar(200).ToString(),
				Convert.ToChar(200).ToString(),
				"11110101110"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"103",
				"START_A",
				"START_A",
				"START_A",
				"11010000100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"104",
				"START_B",
				"START_B",
				"START_B",
				"11010010000"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"105",
				"START_C",
				"START_C",
				"START_C",
				"11010011100"
			});
			this.C128_Code.Rows.Add(new object[]
			{
				"",
				"STOP",
				"STOP",
				"STOP",
				"11000111010"
			});
}

                                                           


 

通过阅读BarCode类生成图片的源码,如下:

private Bitmap Generate_Image()
		{
			if (this.Encoded_Value == "")
			{
				throw new Exception("EGENERATE_IMAGE-1: Must be encoded first.");
			}
			Bitmap bitmap = null;
			DateTime now = DateTime.Now;
			TYPE encoded_Type = this.Encoded_Type;
			if (encoded_Type != TYPE.ITF14)
			{
				bitmap = new Bitmap(this.Width, this.Height);
				int num = this.Width / this.Encoded_Value.Length;
				int num2 = 1;
				if (this.Encoded_Type == TYPE.PostNet)
				{
					num2 = 2;
				}
				int num3;
				switch (this.Alignment)
				{
				case AlignmentPositions.CENTER:
					num3 = this.Width % this.Encoded_Value.Length / 2;
					break;
				case AlignmentPositions.LEFT:
					num3 = 0;
					break;
				case AlignmentPositions.RIGHT:
					num3 = this.Width % this.Encoded_Value.Length;
					break;
				default:
					num3 = this.Width % this.Encoded_Value.Length / 2;
					break;
				}
				if (num <= 0)
				{
					throw new Exception("EGENERATE_IMAGE-2: Image size specified not large enough to draw image. (Bar size determined to be less than 1 pixel)");
				}
				int i = 0;
				using (Graphics graphics = Graphics.FromImage(bitmap))
				{
					graphics.Clear(this.BackColor);
					using (Pen pen = new Pen(this.BackColor, (float)(num / num2)))
					{
						using (Pen pen2 = new Pen(this.ForeColor, (float)(num / num2)))
						{
							while (i < this.Encoded_Value.Length)
							{
								if (this.Encoded_Type == TYPE.PostNet)
								{
									if (this.Encoded_Value[i] != '1')
									{
										graphics.DrawLine(pen2, new Point(i * num + num3 + 1, this.Height), new Point(i * num + num3 + 1, this.Height / 2));
									}
									graphics.DrawLine(pen, new Point(i * (num * num2) + num3 + num + 1, 0), new Point(i * (num * num2) + num3 + num + 1, this.Height));
								}
								if (this.Encoded_Value[i] == '1')
								{
									graphics.DrawLine(pen2, new Point(i * num + num3 + 1, 0), new Point(i * num + num3 + 1, this.Height));
								}
								i++;
							}
						}
					}
				}
				if (this.IncludeLabel)
				{
					this.Label_Generic(bitmap);
				}
			}
			else
			{
				bitmap = new Bitmap(this.Width, this.Height);
				int num4 = (int)((double)bitmap.Width / 12.05);
				int num5 = Convert.ToInt32((double)bitmap.Width * 0.05);
				int num = (bitmap.Width - num4 * 2 - num5 * 2) / this.Encoded_Value.Length;
				int num3 = (bitmap.Width - num4 * 2 - num5 * 2) % this.Encoded_Value.Length / 2;
				if (num <= 0 || num5 <= 0)
				{
					throw new Exception("EGENERATE_IMAGE-3: Image size specified not large enough to draw image. (Bar size determined to be less than 1 pixel or quiet zone determined to be less than 1 pixel)");
				}
				int i = 0;
				using (Graphics graphics = Graphics.FromImage(bitmap))
				{
					graphics.Clear(this.BackColor);
					using (Pen pen2 = new Pen(this.ForeColor, (float)num))
					{
						pen2.Alignment = PenAlignment.Right;
						while (i < this.Encoded_Value.Length)
						{
							if (this.Encoded_Value[i] == '1')
							{
								graphics.DrawLine(pen2, new Point(i * num + num3 + num4 + num5, 0), new Point(i * num + num3 + num4 + num5, this.Height));
							}
							i++;
						}
						pen2.Width = (float)bitmap.Height / 8f;
						pen2.Color = this.ForeColor;
						pen2.Alignment = PenAlignment.Inset;
						graphics.DrawLine(pen2, new Point(0, 0), new Point(bitmap.Width, 0));
						graphics.DrawLine(pen2, new Point(0, bitmap.Height), new Point(bitmap.Width, bitmap.Height));
						graphics.DrawLine(pen2, new Point(0, 0), new Point(0, bitmap.Height));
						graphics.DrawLine(pen2, new Point(bitmap.Width, 0), new Point(bitmap.Width, bitmap.Height));
					}
				}
				if (this.IncludeLabel)
				{
					this.Label_ITF14(bitmap);
				}
			}
			this._Encoded_Image = bitmap;
			this._EncodingTime += (DateTime.Now - now).TotalMilliseconds;
			return bitmap;
		}

影响一维码生成结果有

1   AlignmentPositions对齐方式:靠左、居中、靠右和默认

带你人工识别C#开源库BarcodeLib生成的一维码Code128_第10张图片

2  一维码的宽度,如果宽度不够,那就绘制的线条不全,就会出现无法识别的问题

你可能感兴趣的:(C#编程,c#,人工解码,code28,一维码,原理,BarcodeLib)