.NET二维码

建议不要用CODE-39码,改用CODE-128码;

CODE-39码密度比较低,条码数字内容太多,导致条码太长,缩短长度就只能减小X尺寸,造成识读困难;

CODE-128码密度高,相同的数字生成条码更短。

你可以对比一下图中的两个条码,上面是CODE-39,下面是CODE-128,相同的内容:

解决方案:

Default.aspx

 1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BarcodeTest.Default" %>
 2
 3 <!DOCTYPE html>
 4
 5 <html xmlns="http://www.w3.org/1999/xhtml">
 6 <head runat="server">
 7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 8     <title>条形码</title>
 9     <script type="text/javascript" src="jquery-latest.min.js"></script>
10     <script type="text/javascript">
11         $(function () {
12             $("#btnBar").click(function () {
13                 var rawData = $.trim($("#txtRawData").val());
14                 $("#imgBarcode").attr("src", "BarcodeHandler.ashx?RawData=" + rawData + "&BarHeight=50&BarcodeType=" + $("#ddlBarcodeType").val()
15                     + "&IsDisplayFontData=" + ($("#cbIsDisplayFontData").attr("checked") == "checked") + "&FontSize=" + $("#txtFontSize").val() + "&FontAlignment=" + $("#ddlFontAlignment").get(0).selectedIndex);
16             });
17         });
18     </script>
19 </head>
20 <body>
21     <form id="form1" runat="server">
22         <div>
23             原始码:
24             <input type="text" id="txtRawData" maxlength="48" value="BJ-BJSJF-GCSG-0004-HTFY00002" />
25             <br />
26             编码选择:<select id="ddlBarcodeType"><option>Auto</option>
27                 <option>A</option>
28                 <option>B</option>
29                 <option>C</option>
30             </select>
31         </div>
32         <br />
33         字体大小:<input type="text" id="txtFontSize" value="16" />字体布局:<select id="ddlFontAlignment"><option>Near</option>
34             <option selected="selected">Center</option>
35             <option>Far</option>
36         </select><input checked="checked" type="checkbox" id="cbIsDisplayFontData" />字体显示
37         <div>
38             <input type="button" id="btnBar" value="生成条形码" />
39         </div>
40         <div style="text-align: center;">
41             <img id="imgBarcode" src="" alt="条形码" />
42         </div>
43     </form>
44 </body>
45 </html>

BarcodeHandler.ashx

 1 using Barcode;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6
 7 namespace BarcodeTest
 8 {
 9     /// <summary>
10     /// author: Kenmu
11     /// created by: 2014-11-06
12     /// function: 条形码生成
13     /// </summary>
14     public class BarcodeHandler : IHttpHandler
15     {
16
17         public void ProcessRequest(HttpContext context)
18         {
19             HttpRequest request = context.Request;
20             HttpResponse response = context.Response;
21             response.ClearContent();
22             response.ContentType = "image/jpeg";
23
24             string barcodeType = request["BarcodeType"] ?? "Auto";
25             string rawData = request["RawData"] ?? ((char)20).ToString() + @"123a" + ((char)18).ToString() + "ab";
26             byte barHeight = byte.Parse(string.IsNullOrEmpty(request["BarHeight"]) ? "32" : request["BarHeight"]);
27             bool isDisplayFontData = string.IsNullOrEmpty(request["IsDisplayFontData"]) ? true : bool.Parse(request["IsDisplayFontData"]);
28             int fontSize = string.IsNullOrEmpty(request["FontSize"]) ? 16 : int.Parse(request["FontSize"]);
29             int fontAlignment = string.IsNullOrEmpty(request["FontAlignment"]) ? 1 : int.Parse(request["FontAlignment"]);//0(Near左)、1(Center中)、2(Far右)
30             BaseCode128 code128;
31             switch (barcodeType)
32             {
33                 case "A":
34                     code128 = new Code128A(rawData);
35                     break;
36                 case "B":
37                     code128 = new Code128B(rawData);
38                     break;
39                 case "C":
40                     code128 = new Code128C(rawData);
41                     break;
42                 case "Auto":
43                 default:
44                     code128 = new Code128Auto(rawData);
45                     break;
46             }
47             code128.BarHeight = barHeight;
48             code128.IsDisplayFontData = isDisplayFontData;
49             code128.FontSize = fontSize;
50             code128.FontAlignment = (System.Drawing.StringAlignment)fontAlignment;
51
52             System.Drawing.Image img = code128.GetBarCodeImage();
53             img.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
54             img.Dispose();
55         }
56
57         public bool IsReusable
58         {
59             get
60             {
61                 return false;
62             }
63         }
64     }
65 }

CharacterSet.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5
 6 //author: Kenmu
 7 //created by: 2014-11-05
 8 //function: 条形码
 9 namespace Barcode
10 {
11     /// <summary>
12     /// Code128字符集
13     /// </summary>
14     internal enum CharacterSet
15     {
16         A,
17         B,
18         C
19     }
20 }

IBarCode.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Drawing;
 4 using System.Linq;
 5 using System.Text;
 6
 7 //author: Kenmu
 8 //created by: 2014-11-05
 9 //function: 条形码
10 namespace Barcode
11 {
12     /// <summary>
13     /// 条形码接口
14     /// </summary>
15     public interface IBarCode
16     {
17         string RawData { get; }
18         /// <summary>
19         /// 条形码对应的数据
20         /// </summary>
21         string EncodedData { get; }
22         /// <summary>
23         /// 当前条形码标准
24         /// </summary>
25         string BarCodeType { get; }
26
27         /// <summary>
28         /// 得到条形码对应的图片
29         /// </summary>
30         /// <returns></returns>
31         Image GetBarCodeImage();
32     }
33 }

BaseCode128.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Drawing;
  6
  7 //author: Kenmu
  8 //created by: 2014-11-06
  9 //function: 条形码
 10 namespace Barcode
 11 {
 12     /// <summary>
 13     /// BaseCode128抽象类
 14     /// </summary>
 15     public abstract class BaseCode128 : IBarCode
 16     {
 17         protected Color backColor = Color.White;//条码背景色
 18         protected Color barColor = Color.Black;//条码和原始数据字体颜色
 19
 20         /// <summary>
 21         /// 当前条形码种类
 22         /// </summary>
 23         public string BarCodeType
 24         {
 25             get { return System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name; }
 26         }
 27
 28         /// <summary>
 29         /// 条形码对应的编码数据
 30         /// </summary>
 31         protected string _EncodedData;
 32         public string EncodedData
 33         {
 34             get { return this._EncodedData; }
 35         }
 36
 37         /// <summary>
 38         /// 【原始数据】
 39         /// </summary>
 40         protected string _RawData;
 41         public string RawData
 42         {
 43             get { return this._RawData; }
 44         }
 45
 46         /// <summary>
 47         /// 在条形码下面显示数据;如果为空,则取【原始数据】
 48         /// </summary>
 49         protected string _PresentationData = null;
 50         public string PresentationData
 51         {
 52             get { return string.IsNullOrEmpty(this._PresentationData) ? this._RawData : this._PresentationData; }
 53         }
 54
 55         /// <summary>
 56         /// 条码单位宽度;单位Pix,默认为1
 57         /// </summary>
 58         protected byte _BarCellWidth = 1;
 59         public byte BarCellWidth
 60         {
 61             get { return this._BarCellWidth; }
 62             set
 63             {
 64                 if (value == 0)
 65                 {
 66                     this._BarCellWidth = 1;
 67                 }
 68                 else
 69                 {
 70                     this._BarCellWidth = value;
 71                 }
 72             }
 73         }
 74
 75         /// <summary>
 76         /// 条码高度,必须至少是条码宽度的0.15倍或6.35mm,两者取大者;默认按照实际为32,单位mm
 77         /// </summary>
 78         protected byte _BarHeight = 32;
 79         public byte BarHeight
 80         {
 81             get { return this._BarHeight; }
 82             set
 83             {
 84                 this._BarHeight = value;
 85             }
 86         }
 87
 88         /// <summary>
 89         /// 是否在条形码下面显示【原始数据】
 90         /// </summary>
 91         protected bool _IsDisplayFontData = true;
 92         public bool IsDisplayFontData
 93         {
 94             get { return this._IsDisplayFontData; }
 95             set { this._IsDisplayFontData = value; }
 96         }
 97
 98         /// <summary>
 99         /// 【原始数据】与条形码的空间间隔;单位Pix,默认为4
100         /// </summary>
101         protected byte _FontPadding = 4;
102         public byte FontPadding
103         {
104             get { return this._FontPadding; }
105             set { this._FontPadding = value; }
106         }
107
108         /// <summary>
109         /// 【原始数据】字体大小;单位Pix,默认为16
110         /// </summary>
111         protected float _FontSize = 16;
112         public float FontSize
113         {
114             get { return this._FontSize; }
115             set { this._FontSize = value; }
116         }
117
118         /// <summary>
119         /// 【原始数据】字体布局位置;默认水平居中
120         /// </summary>
121         protected StringAlignment _FontAlignment = StringAlignment.Center;
122         public StringAlignment FontAlignment
123         {
124             get { return this._FontAlignment; }
125             set { this._FontAlignment = value; }
126         }
127
128         public BaseCode128(string rawData)
129         {
130             this._RawData = rawData;
131             if (string.IsNullOrEmpty(this._RawData))
132             {
133                 throw new Exception("空字符串无法生成条形码");
134             }
135             this._RawData = this._RawData.Trim();
136             if (!this.RawDataCheck())
137             {
138                 throw new Exception(rawData + " 不符合 " + this.BarCodeType + " 标准");
139             }
140             this._EncodedData = this.GetEncodedData();
141         }
142
143         protected int GetBarCodePhyWidth()
144         {
145             //在212222这种BS单元下,要计算bsGroup对应模块宽度的倍率
146             //应该要将总长度减去1(因为Stop对应长度为7),然后结果乘以11再除以6,与左右空白相加后再加上2(Stop比正常的BS多出2个模块组)
147             int bsNum = (this._EncodedData.Length - 1) * 11 / 6 + 2;
148             return bsNum * this._BarCellWidth;
149         }
150
151         /// <summary>
152         /// 数据输入正确性验证
153         /// </summary>
154         /// <returns></returns>
155         protected abstract bool RawDataCheck();
156
157         /// <summary>
158         /// 获取当前Data对应的编码数据(条空组合)
159         /// </summary>
160         /// <returns></returns>
161         protected abstract string GetEncodedData();
162
163         /// <summary>
164         /// 获取完整的条形码
165         /// </summary>
166         /// <returns></returns>
167         public Image GetBarCodeImage()
168         {
169             Image barImage = this.GetBarOnlyImage();
170             int width = barImage.Width;
171             int height = barImage.Height;
172             if (this._IsDisplayFontData)
173             {
174                 height += this._FontPadding + (int)this._FontSize;
175             }
176
177             Image image = new Bitmap(width, height);
178             Graphics g = Graphics.FromImage(image);
179             g.Clear(this.backColor);
180             g.DrawImage(barImage, 0, 0, barImage.Width, barImage.Height);
181
182             if (this._IsDisplayFontData)
183             {
184                 Font drawFont = new Font(new FontFamily("Times New Roman"), this._FontSize, FontStyle.Regular, GraphicsUnit.Pixel);
185                 Brush drawBrush = new SolidBrush(this.barColor);
186                 StringFormat drawFormat = new StringFormat();
187                 drawFormat.Alignment = this._FontAlignment;
188                 RectangleF reF = new RectangleF(0, barImage.Height + this._FontPadding, width, this._FontSize);
189                 g.DrawString(this.PresentationData, drawFont, drawBrush, reF, drawFormat);
190
191                 drawFont.Dispose();
192                 drawBrush.Dispose();
193                 drawFormat.Dispose();
194             }
195
196             System.IO.MemoryStream ms = new System.IO.MemoryStream();
197             image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
198             //结束绘制
199             g.Dispose();
200             image.Dispose();
201             return Image.FromStream(ms);
202         }
203         /// <summary>
204         /// 获取仅包含条形码的图像
205         /// </summary>
206         /// <returns></returns>
207         private Image GetBarOnlyImage()
208         {
209             int width = (int)this.GetBarCodePhyWidth();
210             Bitmap image = new Bitmap(width, this._BarHeight);
211             int ptr = 0;
212             for (int i = 0; i < this._EncodedData.Length; i++)
213             {
214                 int w = (int)char.GetNumericValue(this._EncodedData[i]);
215                 w *= this._BarCellWidth;
216                 Color c = i % 2 == 0 ? this.barColor : this.backColor;
217                 for (int j = 0; j < w; j++)
218                 {
219                     for (int h = 0; h < this._BarHeight; h++)
220                     {
221                         image.SetPixel(ptr, h, c);
222                     }
223                     ptr++;
224                 }
225             }
226             return image;
227         }
228     }
229 }

Code128.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Text.RegularExpressions;
  6
  7 //author: Kenmu
  8 //created by: 2014-11-05
  9 //function: 条形码
 10 namespace Barcode
 11 {
 12     /// <summary>
 13     /// Code128基础相关类
 14     /// </summary>
 15     public static class Code128
 16     {
 17         /*
 18              *  128  尺寸要求
 19              *  最小模块宽度 x  最大1.016mm,最小0.250mm 一个系统中的x应为一恒定值  标准是1mm,放大系数0.25~1.2
 20              *  左右侧空白区最小宽度为 10x
 21              *  条高通常为32mm,实际可以根据具体要求
 22              *
 23              * 最大物理长度不应超过 165mm,可编码的最大数据字符数为48,其中包括应用标识符和作为分隔符使用的FNC1字符,但不包括辅助字符和校验符
 24              *
 25              * AI中FNC1同样作为分隔符使用
 26              *
 27              * ASCII
 28              * 0~31 StartA  专有
 29              * 96~127 StartB 专有
 30          *
 31          * EAN128不使用空格(ASCII码32)
 32         */
 33
 34         /// <summary>
 35         /// Code128条空排列集合,1代表条b,0代表空s,Index对应符号字符值S
 36         /// </summary>
 37         internal static readonly List<string> BSList = new List<string>()
 38         {
 39                 "212222" , "222122" , "222221" , "121223" , "121322" , "131222" , "122213" , "122312" , "132212" , "221213" ,
 40                 "221312" , "231212" , "112232" , "122132" , "122231" , "113222" , "123122" , "123221" , "223211" , "221132" ,
 41                 "221231" , "213212" , "223112" , "312131" , "311222" , "321122" , "321221" , "312212" , "322112" , "322211" ,
 42                 "212123" , "212321" , "232121" , "111323" , "131123" , "131321" , "112313" , "132113" , "132311" , "211313" ,
 43                 "231113" , "231311" , "112133" , "112331" , "132131" , "113123" , "113321" , "133121" , "313121" , "211331" ,
 44                 "231131" , "213113" , "213311" , "213131" , "311123" , "311321" , "331121" , "312113" , "312311" , "332111" ,
 45                 "314111" , "221411" , "431111" , "111224" , "111422" , "121124" , "121421" , "141122" , "141221" , "112214" ,
 46                 "112412" , "122114" , "122411" , "142112" , "142211" , "241211" , "221114" , "413111" , "241112" , "134111" ,
 47                 "111242" , "121142" , "121241" , "114212" , "124112" , "124211" , "411212" , "421112" , "421211" , "212141" ,
 48                 "214121" , "412121" , "111143" , "111341" , "131141" , "114113" , "114311" , "411113" , "411311" , "113141" ,
 49                 "114131" , "311141" , "411131" , "211412" , "211214" , "211232" , "2331112"
 50         };
 51
 52         internal const byte FNC3_AB = 96, FNC2_AB = 97, SHIFT_AB = 98, CODEC_AB = 99, CODEB_AC = 100, CODEA_BC = 101;
 53         internal const byte FNC4_A = 101, FNC4_B = 100;
 54         internal const byte FNC1 = 102, StartA = 103, StartB = 104, StartC = 105;
 55         internal const byte Stop = 106;
 56
 57         /// <summary>
 58         /// 获取字符在字符集A中对应的符号字符值S
 59         /// </summary>
 60         /// <param name="c"></param>
 61         /// <returns></returns>
 62         internal static byte GetSIndexFromA(char c)
 63         {
 64             byte sIndex = (byte)c;
 65             //字符集A中 符号字符值S 若ASCII<32,则 S=ASCII+64 ,若95>=ASCII>=32,则S=ASCII-32
 66             if (sIndex < 32)
 67             {
 68                 sIndex += 64;
 69             }
 70             else if (sIndex < 96)
 71             {
 72                 sIndex -= 32;
 73             }
 74             else
 75             {
 76                 throw new NotImplementedException();
 77             }
 78             return sIndex;
 79         }
 80         /// <summary>
 81         /// 获取字符在字符集B中对应的符号字符值S
 82         /// </summary>
 83         /// <param name="c"></param>
 84         /// <returns></returns>
 85         internal static byte GetSIndexFromB(char c)
 86         {
 87             byte sIndex = (byte)c;
 88             if (sIndex > 31 && sIndex < 128)
 89             {
 90                 sIndex -= 32;//字符集B中ASCII码 减去32后就等于符号字符值
 91             }
 92             else
 93             {
 94                 throw new NotImplementedException();
 95             }
 96             return sIndex;
 97         }
 98         internal static byte GetSIndex(CharacterSet characterSet, char c)
 99         {
100             switch (characterSet)
101             {
102                 case CharacterSet.A:
103                     return GetSIndexFromA(c);
104                 case CharacterSet.B:
105                     return GetSIndexFromB(c);
106                 default:
107                     throw new NotImplementedException();
108             }
109         }
110         /// <summary>
111         /// 判断指定字符是否仅属于指定字符集
112         /// </summary>
113         /// <param name="characterSet"></param>
114         /// <param name="c"></param>
115         /// <returns></returns>
116         internal static bool CharOnlyBelongsTo(CharacterSet characterSet, char c)
117         {
118             switch (characterSet)
119             {
120                 case CharacterSet.A:
121                     return (byte)c < 32;
122                 case CharacterSet.B:
123                     return (byte)c > 95 && (byte)c < 128;
124                 default:
125                     throw new NotImplementedException();
126             }
127         }
128         /// <summary>
129         /// 判断指定字符是否不属于指定字符集
130         /// </summary>
131         /// <param name="characterSet"></param>
132         /// <param name="c"></param>
133         /// <returns></returns>
134         internal static bool CharNotBelongsTo(CharacterSet characterSet, char c)
135         {
136             switch (characterSet)
137             {
138                 case CharacterSet.A:
139                     return (byte)c > 95;
140                 case CharacterSet.B:
141                     return (byte)c < 32 && (byte)c > 127;
142                 default:
143                     throw new NotImplementedException();
144             }
145         }
146         /// <summary>
147         /// 当编码转换时,获取相应的切换符对应的符号字符值
148         /// </summary>
149         /// <param name="newCharacterSet"></param>
150         /// <returns></returns>
151         internal static byte GetCodeXIndex(CharacterSet newCharacterSet)
152         {
153             switch (newCharacterSet)
154             {
155                 case CharacterSet.A:
156                     return CODEA_BC;
157                 case CharacterSet.B:
158                     return CODEB_AC;
159                 default:
160                     return CODEC_AB;
161             }
162         }
163         /// <summary>
164         /// 获取转换后的字符集
165         /// </summary>
166         /// <param name="characterSet"></param>
167         /// <returns></returns>
168         internal static CharacterSet GetShiftCharacterSet(CharacterSet characterSet)
169         {
170             switch (characterSet)
171             {
172                 case CharacterSet.A:
173                     return CharacterSet.B;
174                 case CharacterSet.B:
175                     return CharacterSet.A;
176                 default:
177                     throw new NotImplementedException();
178             }
179         }
180         /// <summary>
181         /// 获取应采用的字符集
182         /// </summary>
183         /// <param name="data"></param>
184         /// <param name="startIndex">判断开始位置</param>
185         /// <returns></returns>
186         internal static CharacterSet GetCharacterSet(string data, int startIndex)
187         {
188             CharacterSet returnSet = CharacterSet.B;
189             if (Regex.IsMatch(data.Substring(startIndex), @"^\d{4,}"))
190             {
191                 returnSet = CharacterSet.C;
192             }
193             else
194             {
195                 byte byteC = GetProprietaryChar(data, startIndex);
196                 returnSet = byteC < 32 ? CharacterSet.A : CharacterSet.B;
197             }
198             return returnSet;
199         }
200         /// <summary>
201         /// 从指定位置开始,返回第一个大于95(并且小于128)或小于32的字符对应的值
202         /// </summary>
203         /// <param name="data"></param>
204         /// <param name="startIndex"></param>
205         /// <returns>如果没有任何字符匹配,则返回255</returns>
206         internal static byte GetProprietaryChar(string data, int startIndex)
207         {
208             byte returnByte = byte.MaxValue;
209             for (int i = startIndex; i < data.Length; i++)
210             {
211                 byte byteC = (byte)data[i];
212                 if (byteC < 32 || byteC > 95 && byteC < 128)
213                 {
214                     returnByte = byteC;
215                     break;
216                 }
217             }
218             return returnByte;
219         }
220         /// <summary>
221         /// 获取字符串从指定位置开始连续出现数字的个数
222         /// </summary>
223         /// <param name="data"></param>
224         /// <param name="startIndex"></param>
225         /// <returns></returns>
226         internal static int GetDigitLength(string data, int startIndex)
227         {
228             int digitLength = data.Length - startIndex;//默认设定从起始位置开始至最后都是数字
229             for (int i = startIndex; i < data.Length; i++)
230             {
231                 if (!char.IsDigit(data[i]))
232                 {
233                     digitLength = i - startIndex;
234                     break;
235                 }
236             }
237             return digitLength;
238         }
239     }
240 }

Code128A.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5
 6 //author: Kenmu
 7 //created by: 2014-11-05
 8 //function: 条形码
 9 namespace Barcode
10 {
11     /// <summary>
12     /// Code128A条形码,只支持128字符集A(数字、大写字母、控制字符)
13     /// </summary>
14     public class Code128A : BaseCode128
15     {
16         public Code128A(string rawData)
17             : base(rawData)
18         {
19         }
20
21         protected override bool RawDataCheck()
22         {
23             //128字符集A对应的ASCII码范围为0~95
24             foreach (char c in this._RawData)
25             {
26                 byte tempC = (byte)c;
27                 if (tempC <= 95)
28                 {
29                     continue;
30                 }
31                 else
32                 {
33                     return false;
34                 }
35             }
36             return true;
37         }
38
39         protected override string GetEncodedData()
40         {
41             StringBuilder tempBuilder = new StringBuilder();
42             tempBuilder.Append(Code128.BSList[Code128.StartA]);//加上起始符StartA
43             byte sIndex;
44             int checkNum = Code128.StartA;//校验字符
45             for (int i = 0; i < this._RawData.Length; i++)
46             {
47                 sIndex = Code128.GetSIndexFromA(this._RawData[i]);
48                 tempBuilder.Append(Code128.BSList[sIndex]);
49                 checkNum += (i + 1) * sIndex;
50             }
51             checkNum %= 103;
52             tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符
53             tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符
54             return tempBuilder.ToString();
55         }
56     }
57 }

Code128Auto.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5
  6 //author: Kenmu
  7 //created by: 2014-11-05
  8 //function: 条形码
  9 namespace Barcode
 10 {
 11     /// <summary>
 12     /// Code128Auto条形码,遵循长度最小原则
 13     /// </summary>
 14     public class Code128Auto : BaseCode128
 15     {
 16         public Code128Auto(string rawData)
 17             : base(rawData)
 18         {
 19         }
 20
 21         protected override bool RawDataCheck()
 22         {
 23             //Code128对应的ASCII码范围是0~127
 24             foreach (char c in this._RawData)
 25             {
 26                 if ((byte)c > 127)
 27                 {
 28                     return false;
 29                 }
 30             }
 31             return true;
 32         }
 33
 34         protected override string GetEncodedData()
 35         {
 36             StringBuilder tempBuilder = new StringBuilder();
 37
 38             CharacterSet nowCharacterSet = Code128.GetCharacterSet(this._RawData, 0);
 39
 40             int checkNum;//校验字符
 41             switch (nowCharacterSet)
 42             {
 43                 case CharacterSet.A:
 44                     tempBuilder.Append(Code128.BSList[Code128.StartA]);//加上起始符StartA
 45                     checkNum = Code128.StartA;
 46                     break;
 47                 case CharacterSet.B:
 48                     tempBuilder.Append(Code128.BSList[Code128.StartB]);//加上起始符StartB
 49                     checkNum = Code128.StartB;
 50                     break;
 51                 default:
 52                     tempBuilder.Append(Code128.BSList[Code128.StartC]);//加上起始符StartC
 53                     checkNum = Code128.StartC;
 54                     break;
 55             }
 56             int nowWeight = 1, nowIndex = 0;
 57             this.GetEncodedData(tempBuilder, nowCharacterSet, ref nowIndex, ref nowWeight, ref checkNum);
 58
 59             checkNum %= 103;
 60             tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符
 61             tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符
 62             return tempBuilder.ToString();
 63         }
 64         /// <summary>
 65         /// 通用方法
 66         /// </summary>
 67         /// <param name="tempBuilder"></param>
 68         /// <param name="sIndex"></param>
 69         /// <param name="nowWeight"></param>
 70         /// <param name="checkNum"></param>
 71         private void EncodingCommon(StringBuilder tempBuilder, byte sIndex, ref int nowWeight, ref int checkNum)
 72         {
 73             tempBuilder.Append(Code128.BSList[sIndex]);
 74             checkNum += nowWeight * sIndex;
 75             nowWeight++;
 76         }
 77         /// <summary>
 78         /// 获取编码后的数据
 79         /// </summary>
 80         /// <param name="tempBuilder">编码数据容器</param>
 81         /// <param name="nowCharacterSet">当前字符集</param>
 82         /// <param name="i">字符串索引</param>
 83         /// <param name="nowWeight">当前权值</param>
 84         /// <param name="checkNum">当前检验值总和</param>
 85         private void GetEncodedData(StringBuilder tempBuilder, CharacterSet nowCharacterSet, ref int i, ref int nowWeight, ref int checkNum)
 86         {//因为可能存在字符集C,所以i与nowWeight可能存在不一致关系,所以要分别定义
 87             byte sIndex;
 88             switch (nowCharacterSet)
 89             {
 90                 case CharacterSet.A:
 91                 case CharacterSet.B:
 92                     for (; i < this._RawData.Length; i++)
 93                     {
 94                         if (char.IsDigit(this._RawData[i]))
 95                         {
 96                             //数字
 97                             int digitLength = Code128.GetDigitLength(this._RawData, i);
 98                             if (digitLength >= 4)
 99                             {
100                                 //转入CodeC
101                                 if (digitLength % 2 != 0)
102                                 {//奇数位数字,在第一个数字之后插入CodeC字符
103                                     sIndex = Code128.GetSIndex(nowCharacterSet, (this._RawData[i]));
104                                     this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
105                                     i++;
106                                 }
107                                 nowCharacterSet = CharacterSet.C;
108                                 sIndex = Code128.GetCodeXIndex(nowCharacterSet);//插入CodeC切换字符
109                                 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
110                                 this.GetEncodedData(tempBuilder, nowCharacterSet, ref i, ref nowWeight, ref checkNum);
111                                 return;
112                             }
113                             else
114                             {
115                                 //如果小于4位数字,则直接内部循环结束
116                                 for (int j = 0; j < digitLength; j++)
117                                 {
118                                     sIndex = Code128.GetSIndex(nowCharacterSet, (this._RawData[i]));
119                                     this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
120                                     i++;
121                                 }
122                                 i--;//因为上面循环结束后继续外部循环会导致i多加了1,所以要减去1
123                                 continue;
124                             }
125                         }
126                         else if (Code128.CharNotBelongsTo(nowCharacterSet, this._RawData[i]))
127                         {//当前字符不属于目前的字符集
128                             byte tempByte = Code128.GetProprietaryChar(this._RawData, i + 1);//获取当前字符后第一个属于A,或B的字符集
129                             CharacterSet tempCharacterSet = Code128.GetShiftCharacterSet(nowCharacterSet);
130                             if (tempByte != byte.MaxValue && Code128.CharOnlyBelongsTo(nowCharacterSet, (char)tempByte))
131                             {
132                                 //加入转换符
133                                 sIndex = Code128.SHIFT_AB;
134                                 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
135
136                                 sIndex = Code128.GetSIndex(tempCharacterSet, this._RawData[i]);
137                                 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
138                                 continue;
139                             }
140                             else
141                             {
142                                 //加入切换符
143                                 nowCharacterSet = tempCharacterSet;
144                                 sIndex = Code128.GetCodeXIndex(nowCharacterSet);
145                                 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
146                                 this.GetEncodedData(tempBuilder, nowCharacterSet, ref i, ref nowWeight, ref checkNum);
147                                 return;
148                             }
149                         }
150                         else
151                         {
152                             sIndex = Code128.GetSIndex(nowCharacterSet, this._RawData[i]);
153                             this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
154                         }
155                     }
156                     break;
157                 default:
158                     for (; i < this._RawData.Length; i += 2)
159                     {
160                         if (i != this._RawData.Length - 1 && char.IsDigit(this._RawData, i) && char.IsDigit(this._RawData, i + 1))
161                         {
162                             sIndex = byte.Parse(this._RawData.Substring(i, 2));
163                             this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
164                         }
165                         else
166                         {
167                             nowCharacterSet = Code128.GetCharacterSet(this._RawData, i);
168                             //插入转换字符
169                             sIndex = Code128.GetCodeXIndex(nowCharacterSet);
170                             this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum);
171                             this.GetEncodedData(tempBuilder, nowCharacterSet, ref i, ref nowWeight, ref checkNum);
172                             return;
173                         }
174                     }
175                     break;
176             }
177         }
178     }
179 }

Code128B.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5
 6 //author: Kenmu
 7 //created by: 2014-11-05
 8 //function: 条形码
 9 namespace Barcode
10 {
11     /// <summary>
12     /// Code128B条形码,只支持128字符集B(数字、大小字母、字符)
13     /// </summary>
14     public class Code128B : BaseCode128
15     {
16         public Code128B(string rawData)
17             : base(rawData)
18         {
19         }
20
21         protected override bool RawDataCheck()
22         {
23             //128字符集B对应的ASCII码范围为32~127
24             foreach (char c in this._RawData)
25             {
26                 byte tempC = (byte)c;
27                 if (tempC >= 32 && tempC <= 127)
28                 {
29                     continue;
30                 }
31                 else
32                 {
33                     return false;
34                 }
35             }
36             return true;
37         }
38
39         protected override string GetEncodedData()
40         {
41             StringBuilder tempBuilder = new StringBuilder();
42             tempBuilder.Append(Code128.BSList[Code128.StartB]);//加上起始符StartB
43             byte sIndex;
44             int checkNum = Code128.StartB;//校验字符
45             for (int i = 0; i < this._RawData.Length; i++)
46             {
47                 sIndex = Code128.GetSIndexFromB(this._RawData[i]);//字符集B中ASCII码 减去32后就等于符号字符值
48                 tempBuilder.Append(Code128.BSList[sIndex]);
49                 checkNum += (i + 1) * sIndex;
50             }
51             checkNum %= 103;
52             tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符
53             tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符
54             return tempBuilder.ToString();
55         }
56     }
57 }

Code128C.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Text.RegularExpressions;
 6
 7 //author: Kenmu
 8 //created by: 2014-11-05
 9 //function: 条形码
10 namespace Barcode
11 {
12     /// <summary>
13     /// Code128C条形码,只支持128字符集C(双位数字)
14     /// </summary>
15     public class Code128C : BaseCode128
16     {
17         public Code128C(string rawData)
18             : base(rawData)
19         {
20         }
21
22         protected override bool RawDataCheck()
23         {
24             return Regex.IsMatch(this._RawData, @"^\d{2,96}$") && this._RawData.Length % 2 == 0;//Code128C 2个数字代表一个数据字符,所以最大可以96个数字
25         }
26
27         protected override string GetEncodedData()
28         {
29             StringBuilder tempBuilder = new StringBuilder();
30             tempBuilder.Append(Code128.BSList[Code128.StartC]);//加上起始符StartC
31             byte sIndex;
32             int checkNum = Code128.StartC;//校验字符,StartC为105
33             for (int i = 0; i < this._RawData.Length / 2; i++)
34             {
35                 sIndex = byte.Parse(this._RawData.Substring(i * 2, 2));
36                 tempBuilder.Append(Code128.BSList[sIndex]);
37                 checkNum += (i + 1) * sIndex;
38             }
39             checkNum %= 103;
40             tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符
41             tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符
42             return tempBuilder.ToString();
43         }
44     }
45 }

如有需要,请点击下面链接进行下载:

基于128位的条形码Barcode.zip

时间: 2024-08-06 07:58:48

.NET二维码的相关文章

二维码扫码积分系统定制开发

微信积分系统 二维码扫码积分系统定制开发找丽姐[158.1816.6626/电微]二维码营销模式系统定制开发 微信扫二维码营销系统开发 扫码领积分系统开发 一.如何实现扫二维码领红包功能? 1.使用扫描二维码领取红包对活动进行设置,包括红包数量.红包金额.促销地区.中奖概率等. 2.将生成的二维码赋到商品上面并赋涂层,一方面可以起到保证二维码的一次性,另一方面也可以引起消费者的好奇心. 3.通过手机微信打开扫一扫,扫码商品二维码关注公众号并领取红包,如果参与分享还可以获得抽奖的机会. 二.微信扫

微信生成二维码 只需一个网址即刻 还有jquery生成二维码

<div class="orderDetails-info"> <img src="http://qr.topscan.com/api.php?text=http://123.net/index.php?s=/Home/Index/yanzheng/mai/{$dange.id}" style="width: 5rem; margin-bottom: 1rem;" > </div> http://qr.tops

家电二维码售后服务平台系统开发

家电二维码售后服务平台系统开发,家电二维码售后系统开发,小吴183.2071.6434微电,家电二维码售后软件开发,家电二维码售后平台开发. 互联网平台的节点有两大类型:第一基数节点,也就是弱连接的节点,其规模要大,越大越好,互联网的价值与节点数的平比成正比.第二活跃节点,也就是强连接的节点,其能量要强,越强越好,互联网的价值与其强度成正比. 一.家电维修行业"维修黑幕"层出不穷 记者从一位从事家电维修人士那里了解到,目前行业公认当前家电维修行业有陷阱,"维修黑幕"

微信小程序(4)--二维码窗口

微信小程序二维码窗口: <view class="btn" bindtap="powerDrawer" data-statu="open">button</view> <!--mask--> <view class="drawer_screen" bindtap="powerDrawer" data-statu="close" wx:if=&qu

微信服务器与项目服务器的交互(关注功能、微信扫描带参数二维码)

<?php /** * wechat php test */ //define your token define("TOKEN", "txtj"); $wechatObj = new wechatCallbackapiTest(); if (isset($_GET['echostr'])) { $wechatObj->valid(); }else{ $wechatObj->responseMsg(); } class wechatCallback

Java生成微信二维码及logo二维码

依赖jar包 QrCode.jar:https://pan.baidu.com/s/1c1PYV0s 加入本地 maven: mvn install:install-file -Dfile=QRCode.jar -DgroupId=QRCode -DartifactId=QRCode -Dversion=3.0 -Dpackaging=jar 实例源码 import com.swetake.util.Qrcode; import javax.imageio.ImageIO; import jav

二维码扫描

1.将ZBar的SDK导入工程 SDK下载地址:https://i.cnblogs.com/Files.aspx 或者去官网下载:https://github.com/bmorton/ZBarSDK 2.设置依赖库 需要添加AVFoundation  CoreMedia  CoreVideo QuartzCore libiconv 3.修改工程配置 1)      Framework Search Path 2)      如果使用xcode7.0以上 ,还需设置: /* 4. 版本说明  1.

二维码生成类

import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.z

iOS使用AVFoundation实现二维码扫描

实现过程如下: Step1:需要导入:AVFoundation Framework 包含头文件: #import <AVFoundation/AVFoundation.h> Step2:设置捕获会话 设置 AVCaptureSession 和 AVCaptureVideoPreviewLayer 成员 1 2 3 4 5 6 7 8 9 10 #import <AVFoundation/AVFoundation.h> static const char *kScanQRCodeQu

Java实现二维码QRCode的编码和解码

涉及到的一些主要类库,方便大家下载: 编码lib:Qrcode_swetake.jar   (官网介绍-- http://www.swetake.com/qr/index-e.html) 解码lib:qrcode.jar                 (官网介绍-- http://sourceforge.jp/projects/qrcode/) [一].编码: Java代码QRCodeEncoderHandler.java package michael.qrcode; import java