条码编码-Code39

2023-11-19

近来在研究条码的实现,遇到一些坑,现在把自己遇到的一些情况分享一下。

 

世界上约有225种以上的条形码一般较流行的有 39码、EAN码、UPC 码、128码,以及专门用於书刊管理的ISBN、ISSN等。

 

 

我们先从Code39码开始:

 

  • Code39

 

39码具有以下特性:

条码的长度没有限制,可随着需求作弹性调整。但在规划长度的大小时,应考虑条码阅读机所能允许的范围,避免扫瞄时无法读取完整的资料。


起始码和终止码必须固定为“ * ”字元。允许条码扫瞄器进行双向的扫瞄处理。由於39码具有自我检查能力,故检查码可有可无,不一定要设定。 条码占用的空间较大。

可表示的资料包含有:0~9的数字,A~Z的英文字母,以及“+”、“-”、“*”、“/”、“%”、“$”、“.”等特殊符号,再加上空白字元“ ”,共计44组编码,并可组合出128个ASCII CODE的字元符号,如表所示。

表 ASCII CODE字元符号与39码对照表

 

这里就只研究0~9的数字,A~Z的英文字母,以及“+”、“-”、“*”、“/”、“%”、“$”、“.”等特殊符号,再加上空白字元“ ”,这44组编码,其他ASCII码的组合暂时不考虑;

CODE 39码的编码规则是:

1、9条线表示一个字符;

2、黑线表示1,空线表示0;

3、线宽的表示w,窄的表示n;

4、条形码的首尾各一个*标识开始和结束;

5、宽条和窄条的比率为2-3之间;

6、字符和字符之间的有空白间隔;

7、校验位可不做编码;

编码对映表如下:

字元

逻辑型态

 

字元

逻辑型态

 

A

110101001011

wnnnnwnnwn

N

101011010011

nnnnwnnwwn

B

101101001011

nnwnnwnnwn

O

110101101001

wnnnwnnwnn

C

110110100101

wnwnnwnnnn

P

101101101001

nnwnwnnwnn

D

101011001011

nnnnwwnnwn

Q

101010110011

nnnnnnwwwn

E

110101100101

wnnnwwnnnn

R

110101011001

wnnnnnwwnn

F

101101100101

nnwnwwnnnn

S

101101011001

nnwnnnwwnn

G

101010011011

nnnnnwwnwn

T

101011011001

nnnnwnwwnn

H

110101001101

wnnnnwwnnn

U

110010101011

wwnnnnnnwn

I

101101001101

nnwnnwwnnn

V

100110101011

nwwnnnnnwn

J

101011001101

nnnnwwwnnn

W

110011010101

wwwnnnnnnn

K

110101010011

wnnnnnnwwn

X

100101101011

nwnnwnnnwn

L

101101010011

nnwnnnnwwn

Y

110010110101

wwnnwnnnnn

M

110110101001

wnwnnnnwnn

Z

100110110101

nwwnwnnnnn

 

 

 

 

 

 

 

 

 

 

 

 

0

101001101101

nnnwwnwnnn

100101001001

nwnnnwnwnn

1

110100101011

wnnwnnnnwn

100101011011

nwnnnnwnwn

2

101100101011

nnwwnnnnwn

100101101101

nwnnwnwnnn

3

110110010101

wnwwnnnnnn

100100101001

nwnwnnnwnn

4

101001101011

nnnwwnnnwn

101001001001

nnnwnwnwnn

5

110100110101

wnnwwnnnnn

100100100101

nwnwnwnnnn

6

101100110101

nnwwwnnnnn

110010101101

wwnnnnwnnn

7

101001011011

nnnwnnwnwn

空白

100110101101

nwwnnnwnnn

8

110100101101

wnnwnnwnnn

 

 

9

101100101101

nnwwnnwnnn

 

 

 

这里的逻辑形态,并不包括每个字符之间的空白间隙,所以在编码的时候要再加一个0,很多资料上都未提醒着一点,注意别踩坑。

现在直接上代码:

#include <stdio.h>
#include <string.h>
#include <CODE39.h>
#include "lcd.h"


//ÿ����ʾ�ַ���Ӧ������
const char *Code39DataBuf[43]= {
//ÿ����Ԫ���������9������ɣ��ַ����ַ�֮��Ŀհ׼��������ÿһ������0���ǿհ׼�϶
//1�ú�ɫ�߱����0�ð�ɫ�߱��
// �߼���̬    //��Ԫ      ACSII(DEC)
"1010011011010",// 0           48
"1101001010110",// 1           49
"1011001010110",// 2           50
"1101100101010",// 3           51
"1010011010110",// 4           52
"1101001101010",// 5           53
"1011001101010",// 6           54
"1010010110110",// 7           55
"1101001011010",// 8           56
"1011001011010",// 9           57
"1101010010110",// A           65
"1011010010110",// B           66
"1101101001010",// C           67
"1010110010110",// D           68
"1101011001010",// E           69
"1011011001010",// F           70
"1010100110110",// G           71
"1101010011010",// H           72
"1011010011010",// I           73
"1010110011010",// J           74
"1101010100110",// K           75
"1011010100110",// L           76
"1101101010010",// M           77
"1010110100110",// N           78
"1101011010010",// O           79
"1011011010010",// P           80
"1010101100110",// Q           81
"1101010110010",// R           82
"1011010110010",// S           83
"1010110110010",// T           84
"1100101010110",// U           85
"1001101010110",// V           86
"1100110101010",// W           87
"1001011010110",// X           88
"1100101101010",// Y           89
"1001101101010",// Z           90
"1001010110110",// -           45
"1100101011010",// .           46
"1001101011010",// sp          32
"1001001001010",// $           36
"1001001010010",// /           47
"1001010010010",// +           43
"1010010010010",// %           37
};


char *code39_Code(char *CharToShow, u8 len)
{
   //PixelPtr�Ǻ������ص��ָ��
//	char *PixelPtr;
	u8 lcd_id[12];				//���LCD ID�ַ���
	static char PixelPtr[520];
  uint8_t  i,j,CheakID; 
  uint32_t CheakSum = 0;

	const char *Space_CODE39    = "000000000";
	const char *BStartEndBuf    = "1001011011010"; // *
	
	 //����У��λ
  for(i=0; i<len; i++)
  {
    if((CharToShow[i]>='0') && (CharToShow[i]<='9'))      CheakSum+=((CharToShow[i]-'0'));//0~9
    else if((CharToShow[i]>='A') && (CharToShow[i]<='Z')) CheakSum+=((CharToShow[i]-'0')-7);//A~Z
    
		else if(CharToShow[i]=='-') CheakSum+=36;
	  else if(CharToShow[i]=='.') CheakSum+=37;
		else if(CharToShow[i]==' ') CheakSum+=38;
    else if(CharToShow[i]=='&') CheakSum+=39;
    else if(CharToShow[i]=='/') CheakSum+=40;
    else if(CharToShow[i]=='+') CheakSum+=41;
    else if(CharToShow[i]=='%') CheakSum+=42;		
	} 

  CheakID = CheakSum%43;
	sprintf((char*)lcd_id,"LCD ID:%d",CheakID);//
	LCD_ShowString(30,40,210,24,24,lcd_id);
	
	//�����ǿհ�����9�����صĿհ�
   strcat(PixelPtr, Space_CODE39);
	
  //��������ʼ�ַ�*
    strcat(PixelPtr, BStartEndBuf);

    for (int i = 0; i < len; i++)
    {//
			
			if((CharToShow[i]>='0') && (CharToShow[i]<='9'))      strcat(PixelPtr, Code39DataBuf[(CharToShow[i]-'0')]);//0~9
			else if((CharToShow[i]>='A') && (CharToShow[i]<='Z')) strcat(PixelPtr, Code39DataBuf[(CharToShow[i]-'0')-7]);//A~Z
			
			else if(CharToShow[i]=='-') strcat(PixelPtr, Code39DataBuf[36]);//
			else if(CharToShow[i]=='.') strcat(PixelPtr, Code39DataBuf[37]);//
			else if(CharToShow[i]==' ') strcat(PixelPtr, Code39DataBuf[38]);//
			else if(CharToShow[i]=='&') strcat(PixelPtr, Code39DataBuf[39]);//
			else if(CharToShow[i]=='/') strcat(PixelPtr, Code39DataBuf[40]);//
			else if(CharToShow[i]=='+') strcat(PixelPtr, Code39DataBuf[41]);//
			else if(CharToShow[i]=='%') strcat(PixelPtr, Code39DataBuf[42]);//	
    }
		//��
//    strcat(PixelPtr,Code39DataBuf[CheakID]);
		
  //�����ǽ����ַ�*
    strcat(PixelPtr, BStartEndBuf);
		
    return PixelPtr;
}

int CODE39_DISPLAY( char *CODE39_data , u8 len)
{
   	u16 i,j,k;
	  u16 x,y,p;
    char *code;
	
	code = code39_Code(CODE39_data,len);

	p = (3-1)*2;//���С
	x = 24;
	y = 80;
	
	for(i=0;i<strlen(code);i++)//width
	{

		k=41;//height
		for(j=0;j<k;j++)
		{
			if(code[i]>'0')
			{
				LCD_Fill(x+p*i,y+p*j,x+p*(i+1)-1,y+p*(j+1)-1,BLACK);
      }
			else
			{
				
			}
		}
	}

}	

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

条码编码-Code39 的相关文章

  • matlab 回归

    我发现这两天写题目 回归真的是个万能方法 但是我只会最简单的线性回归 为此特地记录一下以下几种方法 1 regress 简单线性回归 可以是一元 也可以是多元 具体用法可以看这个图片 这个方法最简单 也最好用 但是也有局限 比如非线性的时候
  • Unity与Andriod交互错误合集

    一 无法调用安卓中的方法no non static method with name 报错如下 在保证代码中的方法名没有问题 并且调用的方法名的返回值和传递的参数等都没有问题的情况下 第一 查看在Unity项目中jar包存放的位置是否正确
  • 前言 在学习达梦数据库数据存储过程中有接触到行式存储和列式存储方面的内容 在此作简单的学习分享 通过本文你可以了解到行存储模式 列存储模式 它们的优缺点以及列存储模式的优化等知识 Row vs Column Oriented Databas
  • 怎样用计算机的计算器的程序员进行进制,使用系统自带计算器进行二进制运算(示例代码)...

    int x 110 int y 10 Console WriteLine x y Console WriteLine x y 想亲自算一下这种计算的时候 打开windows自带的计算器calc exe 调到 程序员计算器 模式即可 选择DE
  • 华为OD机试 - 日志限流(Java )

    题目描述 某软件系统会在运行过程中持续产生日志 系统每天运行N单位时间 运行期间每单位时间产生的日志条数保行在数组records中 records i 表示第i单位时间内产生日志条数 由于系统磁盘空间限制 每天可记录保存的日志总数上限为to
  • 详解人工智能领域重大突破:GPT-3

    2020 09 14 16 09 导语 GPT 3是自然语言处理 领域迄今为止发布出来最大的Transformer模型 超过之前的记录 微软研究院Turing LG的170亿参数 约10倍 英语原文 Exploring GPT 3 A Ne
  • 剑指 Offer 18. 删除链表的节点 -- 双指针

    0 题目描述 leetcode原题链接 剑指 Offer 18 删除链表的节点 1 双指针解法 删除值为 val 的节点分需为两步 定位节点 修改引用 定位节点 遍历链表 直到 head val val 时跳出 即可定位目标节点 修改引用
  • 荐读

    本文转自 链闻 ChainNews 作者 Karen 虽然区块链技术诞生至今不过短短十余年 但是东西方天然的文化差异在加密世界中同样留下了一些痕迹 当社交媒体上关于 东方区块链 只关心币价 利益和投机而只有 西方区块链 才关心底层技术的革新
  • “元宇宙”既是机遇也是挑战

    一次性看懂元宇宙 是开疆拓土还是新一轮割韭菜 众所周知 随着AI VR AR MR XR 区块链 云计算 物联网 数字孪生 量子技术 5G技术等新兴技术的快速发展 推动刚刚过去的2021年成为元宇宙元年 先是3月Robolox上市 开启了元
  • 基于Dpabi的功能连接

    1 预处理 这里预处理用Gretna软件进行 共分为以下几步 1 DICOM转NIfTI格式 2 去除前10个时间点 Remove first 10 times points 由于机器刚启动 被试刚躺进去也还需适应环境 导致刚开始扫描的数据
  • 分享一个开源免费、功能强大的视频播放器库

    99 的前端开发者都关注了这个公众号 点击上方 前端开发博客 关注并 设为星标 回复加群 自助秒进前端群 最近在开发一个前端项目 用到播放视频的功能 所以就查了下有什么前端的视频播放器库可以使用 今天来分享一下给大家 这个库的名字叫做 Pl
  • Zabbix之自定义监控MySQL主从状态和延迟

    zabbix之自定义监控MySQL主从状态和延迟 文章目录 监控MySQL主从状态 1 安装Mariadb配置主从 2 配置监控脚本 3 web界面添加监控项 4 添加触发器 5 触发验证 监控MySQL主从延迟 配置监控脚本 web界面添
  • 机器学习-knn近邻分类算法

    算法原理 本质是通过距离 欧式距离 判断两个样本是否相似 如果距离够近就认为他们足够相似属于同一类别 算法优缺点 主要参数k 标记数据周围几个数作为参考对象 需要根据数据来决定 k值越大 模型偏差大 对噪声数据不敏感 可能造成欠拟合 k值越
  • 若依文件下载

    若依文件下载 都看我的 2021 4 17 找了一圈 每一个写的简单的 还得自己完成 提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 前台代码 二 加入js代码 总结 前言 提示 若依框架的文件下载 提
  • css 让内容可滑动,css实现隐藏滚动条并可以滚动内容

    代码预览 行走在光阴里的人 谁不对初见怀揣一份美好向往和期待 谁不对初见心存一份眷恋和不舍 假如人生是一场途经 初见一定是人生路上最美的绽放 人生在世 不管你是青丝如云 还是白发如霜 当你念及 人生若只如初见 时 你的嘴角一定会不由自主地泛
  • ChatGTP套壳网站总结更新

    总结一批ChatGTP套壳网站供大家学习参考 前10个网站经过测试可用 所以套壳网站 就是使用ChatGPT提供的API与ChatGPT系统连接 使用自己的网站来实现交互展示 效果与在ChatpGPT网站上聊天是一样的 ChatGTP套壳网
  • HTC-VIVE手柄使用代码

    using UnityEngine using System Collections 检测手柄功能的脚本 这个脚本挂到手柄上 controler right 和controler left 上 public class ButtonTouc
  • java包装类&简单认识泛型

    1 包装类 在 Java 中 由于基本类型不是继承自 Object 为了在泛型代码中可以支持基本类型 Java 给每个基本类型都对应了一个包装 类型 类中比如由属性 方法 使用比较方便 1 1 基本数据类型和对应的包装类 1 2 装箱和拆箱
  • vtk使用之Mapper和actor的关联

    参考博客 VTK的Mapper Dezeming的博客 CSDN博客 vtk mapper VTK 图形进阶 vtkPolyData数据生成与显示 简 单的博客 CSDN博客 vtkpolydata 类vtkMapper及其派生类 把输入的

随机推荐

  • 引入微信支付Java SDK WxPayAPI_JAVA.zip

    最近需要接入微信支付 百度了很多博客 关键第一步导入微信支付提供的官方sdk就卡住了 那些博客上也没说怎么导入 以前没整过sdk 一下懵了 后来发现WxPayAPI JAVA zip解压出来的文件是个maven项目 然后直接IDEA打开这个
  • Java基础知识总结(三)

    java的代码块分类 局部代码块 比较简单 在局部位置 方法定义中 定义的 作用 限定某个变量的生命周期 构造代码块 在类的成员位置 作用 在执行构造方法之前 如果存在构造代码块 优先执行构造代码块 可以将构造方法中共性内容 放在构造代码中
  • [渗透]CVE-2020-1938/CNVD-2020-10487:Apache Tomcat AJP连接器远程执行代码漏洞

    受影响版本 Apache Tomcat 6 Apache Tomcat 7x lt 7 0 100 Apache Tomcat 8x lt 8 5 51 Apache Tomcat 9x lt 9 0 31 未受影响版本 Tomcat 7
  • 设计模式(十)装饰器模式

    装饰器模式是一种非常有用的结构型模式 它允许我们在不改变类的结果的情况下 为类添加新的功能 我们来举例说明一下 首先添加一组形状 它们都实现了形状接口 public interface Shape String getShape class
  • QT使用emit时发生内存泄露

    1 场景 在QT里面使用多线程进行编程时 子线程执行的函数里面使用了emit发生了内存泄露 2 主要原因 在使用子线程时 线程使用了join 来等待子线程完成 这样使用emit也不会发送信号 因为join 是阻塞的 必须等待当前线程完成 3
  • iOS逆向工程之App脱壳

    本篇博客以微信为例 给微信脱壳 砸壳 在iOS逆向工程中是经常做的一件事情 因为从AppStore直接下载安装的App是加壳的 其实就是经过加密的 这个 砸壳 的过程就是一个解密的过程 未砸壳的App是无法在Class dump Hoppe
  • Android多进程(一)—— 开启多进程

    Android多进程 一般情况下 一个应用程序就是一个进程 进程名就是应用程序的包名 进程是系统分配资源的基本单位 每个进程都有自己独立的资源和内存空间 1 Android开启多进程的原因 单进程分配的内存不够 需要更多的内存 早期的And
  • STM32H750+LAN8720无操作系统移植lwip

    前言 本文提供移植好的工程 仅使用串口和以太网外设 见本文绑定资源 环境 STM32CubeMX V6 8 1 STM32H7 HAL Pack V1 11 1 硬件连接 STM32H750 GPIO定义如下 LAN8720 GPIO定义如
  • 使用匿名函数动态设置前置或者后置操作(装饰器模式的)

    我的个人博客 逐步前行STEP 在维护另一个同事的代码时 由于代码量比较大而且封装程度低耦合高 维护起来不太顺手 就怕哪没注意把现有的逻辑改坏了 受到laravel admin的保存回调功能的启发 想到了使用匿名函数来动态设置前置或者后置操
  • 一文带你看懂细粒度分类网络Learning Attentive Pairwise Interaction(AAAI)

    论文 https arxiv org abs 2002 10191 引用或转载请注明出处
  • [Vue warn]: Error in render: “TypeError: cellValue.replaceAll is not a function

    去除中括号 如 车门 车门 let reg new RegExp g return str replaceAll reg 上面方法 在edge浏览器 谷歌浏览器没问题 但是在搜狗和QQ浏览器就报错 解决办法 return str repla
  • unity中Input类

    这个是鼠标与键盘按键的一些操作 void Update 获取鼠标在屏幕中的位置 Vector3 mousePos Input mousePosition print mousePos 获取屏幕的宽 Screen width 获取屏幕的高 S
  • 【技术经验分享】计算机毕业设计Python+Spark视频推荐系统 短视频推荐系统 视频流量预测系统 短视频爬虫 视频数据分析 视频可视化 视频大数据 大数据毕业设计 大数据毕设

    开发技术 前端 vue js websocket element ui echarts 后端 springboot mybatis plus 数据库 mysql neo4j图数据库 知识图谱 数据分析 hadoop spark实时计算 算法
  • TscanCode代码扫描工具

    TscanCode介绍 TscanCode 是腾讯研发的静态代码扫描工具 最早的版本是基于 cppcheck 二次开发 之后又重新自研 不仅支持 C 还支持 C Lua 语言 在发掘 C 空指针 越界 未初始化 C 空引用 Lua变量未初始
  • 活动报名|如何使用70万预算从头训练千亿语言大模型

    王业全 北京智源人工智能研究院认知模型团队负责人 清华大学博士 中国中文信息学会情感计算专委会委员 2022年被评为AI 2000全球最具影响力人工智能学者 自然语言处理领域 主要从事语言大模型 自然语言处理方面的研究工作 代表成果有 FL
  • shell脚本读取csv数据迁移文件

    前言 仅记录学习笔记 如有错误欢迎指正 最近 这段时间一直在忙数据迁移的问题 现在碰见的问题是需要将目标服务器上的文件导入到本地库 思路 我们需要的数据不多 但是服务器上特别多 所以通过查询目标文件的目录位置和文件名称 导出为csv文件 之
  • Vue + ElementUI 实现批量删除功能

    第一步 在el table 组件绑定 selection change事件 第二步 在调用父组件的子组件中添加当表格项发生变化时会触发事件函数 selectionChange val 在method 函数中添加如下代码 selectionC
  • 从零基础开始开发自己的第一个微信小程序

    文章目录 内容介绍 小程序开发步骤 注册微信小程序账号 下载开发工具搭建开发环境 创建工程编写代码 手机上查看效果 工程里的文件作用介绍 总结 内容介绍 通过本篇blog 你可以熟悉从零开始 搭建小程序开发环境 并运行起自己的第一个小程序
  • QT中slot,signal,emit讲解

    Qt中的类库有接近一半是从基类QObject上继承下来 信号与反应槽 signals slot 机制就是用来在QObject类或其子类间通讯的方法 作为一种通用的处理机制 信号与反应槽非常灵活 可以携带任意数量的参数 参数的类型也由用户自定
  • 条码编码-Code39

    近来在研究条码的实现 遇到一些坑 现在把自己遇到的一些情况分享一下 世界上约有225种以上的条形码 一般较流行的有 39码 EAN码 UPC 码 128码 以及专门用於书刊管理的ISBN ISSN等 我们先从Code39码开始 Code39