图书馆RFID(射频识别)数据模型压缩/解压缩算法实现小工具

点击下载《C# 实现图书馆射频识别数据模型压缩算法(源代码+pdf参考资料)》

1. 前言

最近闲来无聊,看了一下《图书馆射频识别数据模型第1部分:数据元素的设置及应用规则》以及《图书馆射频识别数据模型第2部分:基于ISO/IEC 15962的数据元素编码方案》,决定根据上面的编码方法实现一下该算法,于是写了一个小工具,本文将围绕这个小工具介绍一下其用法。

2. 详细说明

本程序分别实现了数据的压缩和解压缩两种算法,程序界面如下:

在这里插入图片描述

2.1 开发环境

开发工具:Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.7.6

目标框架:.Net Framework 4.6.2

开发语言:C#

运行环境:Window 10 x86/x64

2.2 数据压缩

馆代码(馆标识):使用馆际互借时用于标识图书馆的唯一编码,格式为:2位国家代码-字母和数字,如:CH-sztsg001
在这里插入图片描述

馆藏地代码:图书馆中用于标识图书所在物理位置的编码,一般由字母和数字组成,如图书馆一楼:tsg001
在这里插入图片描述

应用类别:资料类型以及在图书馆内的用途,参照《图书馆射频识别数据模型第1部分:数据元素的设置及应用规则》中的附录C,这里设置为0x12
在这里插入图片描述

条码号:一般由数字和字母组成,如:TM000000012121
在这里插入图片描述

在这里插入图片描述

输入以上信息后,点击压缩,程序会根据条码的数据类型选择相应的压缩算法进行数据压缩,并输出压缩后的结果。压缩算法可参照《图书馆射频识别数据模型第2部分:基于ISO/IEC 15962的数据元素编码方案》中关于数据编码的部分内容。

2.3 数据解压缩

将压缩后的数据输入至文本框中,点击加压缩即可,程序会自动解析数据,并将结果呈现至馆代码、馆藏地点、应用类别、条码号中。

在这里插入图片描述

3. 代码

3.1 压缩算法

 /// <summary>/// 数据压缩/// </summary>/// <param name="dataType">数据类型(如:条码号 DataTyep.Barcode)</param>/// <param name="data">数据内容</param>/// <param name="userDefineCompressFormat">是否使用自定义压缩模式</param>/// <param name="defaultFormat">自定义压缩模式</param>/// <returns></returns>private static byte[] DataCompress(string data, bool userDefineCompressFormat = false, CompressModel defaultFormat = CompressModel.Number){try{if (data == null || data == ""){return null;}CompressModel format = defaultFormat;if (userDefineCompressFormat){format = defaultFormat;//压缩类型}else{format = GetDataCompressFormat(data);//压缩类型}byte[] btData = null;switch (format){case CompressModel.ISIL:btData = GetConverData0(data);break;case CompressModel.IntNumber:btData = GetConverData1(data);break;case CompressModel.Number:btData = GetConverData2(data);break;case CompressModel.CP_5Bit:btData = GetConverData3(data);break;case CompressModel.CP_6Bit:btData = GetConverData4(data);break;case CompressModel.CP_7Bit:btData = GetConverData5(data);break;case CompressModel.CP_8bit:btData = GetConverData6(data);break;default:btData = Encoding.UTF8.GetBytes(data);break;}if (btData == null){return null;}return btData;}catch (Exception ex){}return null;}/// <summary>/// 获取压缩后的数据/// </summary>/// <param name="orgDataDic"></param>/// <returns></returns>public static byte[] GetCompressData(Dictionary<DataType, string> orgDataDic){try{//每个数据集均由前导字节、编码数据长度、被压缩数据3部分组成Dictionary<DataType, RfidData> cmpDataDic = new Dictionary<DataType, RfidData>();int nDataTotalLen = 0;foreach (var key in orgDataDic.Keys){RfidData data = new RfidData();//馆代码采用固定的ISIL方式编码if (key == DataType.LibraryCode){data.compressFormat = CompressModel.ISIL;}//直接使用8位编码else if (key == DataType.UseType || key == DataType.LocationCode || key == DataType.ONIXMediaFormat){data.compressFormat = CompressModel.CP_8bit;}else{data.compressFormat = GetDataCompressFormat(orgDataDic[key]);}data.strData = orgDataDic[key];if (string.IsNullOrEmpty(data.strData)){continue;}//如果数据大于最大的整数,则采用数字压缩if (data.compressFormat == CompressModel.IntNumber && data.strData.Length >= 18){data.compressFormat = CompressModel.Number;}byte[] btData = DataCompress(orgDataDic[key], true, data.compressFormat);byte nAppLen = 0;byte btFirstByte = 0;bool bFlag = CheckFirstByteData(data.compressFormat, key, btData, out btFirstByte, out nAppLen);//如果为条码号则需要进行填充判断if (key == DataType.BarCode && bFlag){data.byteData = new byte[btData.Length + 3 + nAppLen];//前导符(1byte) + 偏移量(1byte) + 压缩数据长度(1byte) + 填充数据长度(nAppLen)data.byteData[0] = btFirstByte;data.byteData[1] = nAppLen;data.byteData[2] = (byte)btData.Length;Array.Copy(btData, 0, data.byteData, 3, btData.Length);}else{data.byteData = new byte[btData.Length + 2];//前导符(1byte) + 压缩数据长度(1byte)data.byteData[0] = GetFirstByteData(data.compressFormat, key);data.byteData[1] = (byte)btData.Length;Array.Copy(btData, 0, data.byteData, 2, btData.Length);}nDataTotalLen += data.byteData.Length;//数据总长度cmpDataDic.Add(key, data);}return GetFullCompressData(ref cmpDataDic, nDataTotalLen);}catch (Exception ex){                }return null;}       

注:以上仅为部分代码。

3.2 解压缩算法

/// <summary>
/// 解压一个数据块
/// </summary>
/// <param name="btDecData">待解压的数据</param>
/// <param name="nDecType">数据压缩方式</param>
/// <param name="nDataType">数据类型</param>
/// <param name="nDataLen">数据长度</param>
/// <returns></returns>
private static RfidData DataDeCompress(byte[] btDecData, int nDecType, int nDataType)
{try{RfidData data = new RfidData();string strDecData = string.Empty;switch (nDecType){case (int)CompressModel.ISIL:if ((DataType)nDataType == DataType.LibraryCode){strDecData = GetExplodeDate0(btDecData);}else{strDecData = GetExplodeDate6(btDecData);}break;case (int)CompressModel.IntNumber:strDecData = GetExplodeDate1(btDecData);break;case (int)CompressModel.Number:strDecData = GetExplodeDate2(btDecData);break;case (int)CompressModel.CP_5Bit://五位码strDecData = GetExplodeDate3(btDecData);break;case (int)CompressModel.CP_6Bit:strDecData = GetExplodeDate4(btDecData);break;case (int)CompressModel.CP_7Bit:strDecData = GetExplodeDate5(btDecData);break;case (int)CompressModel.CP_8bit:strDecData = GetExplodeDate6(btDecData);break;}DataType dataType = (DataType)nDataType;data.byteData = btDecData;data.compressFormat = (CompressModel)nDecType;data.strData = strDecData;return data;}catch (Exception ex){}return null;
}/// <summary>
/// 解压缩
/// </summary>
/// <param name="strData">16进制(大写)被压缩后的数据</param>
/// <returns></returns>
public static Dictionary<DataType, RfidData> DataDeCompress(string strData)
{try{if (string.IsNullOrEmpty(strData)){return null;}Dictionary<DataType, RfidData> dataDic = new Dictionary<DataType, RfidData>();int nIdx = 0;byte[] btData = StringToByte(strData);do{//取第一个字节和第二个字节byte btFirstData = btData[nIdx];byte btDataLen = 0;nIdx += 1;int nAppLen = 0;//填充数据长度int nDecType = 0;//压缩类型int nDataType = 0;//数据类型byte[] btDecData;//压缩后的数据//判断数据是否有填充和偏移bool bAppFlag = CheckDataAppend(btFirstData, out nDecType, out nDataType);if (nDataType == 0)//有问题的数据块直接算是有效数据终止{break;}if (bAppFlag){nAppLen = btData[nIdx];nIdx += 1;//跳过填充字节btDataLen = btData[nIdx];//标示数据长度nIdx += 1;//跳过数据长度字节//压缩后的数据btDecData = new byte[btDataLen];Array.Copy(btData, nIdx, btDecData, 0, btDataLen);nIdx = nIdx + btDataLen + nAppLen;}else{btDataLen = btData[nIdx];//标示数据长度nIdx += 1;//跳过数据长度字节if (nIdx + btDataLen >= btData.Length){break;}//压缩后的数据btDecData = new byte[btDataLen];Array.Copy(btData, nIdx, btDecData, 0, btDataLen);nIdx += btDataLen;}DataType dataType = (DataType)nDataType;RfidData data = DataDeCompress(btDecData, nDecType, nDataType);if (nDataType > 0 && nDataType < (int)DataType.NotUseFlag){if (!dataDic.ContainsKey(dataType)){dataDic.Add(dataType, data);}}}while (nIdx < btData.Length);return dataDic;}catch (Exception ex){}return null;
}

注:以上仅为部分代码。

4. 总结

程序主要包括两部分的功能:压缩与解压缩,将压缩后的数据作为输入数据可执行解压缩操作,也可用于将使用了支持标准的图书馆射频识别数据模型算法加密的数据进行解压缩,文章中提及的算法代码均为压缩或解压缩代码中的一部分。

4.1 参考资料1

《图书馆射频识别数据模型第1部分:数据元素的设置及应用规则》
在这里插入图片描述

4.2 参考资料2

《图书馆射频识别数据模型第2部分:基于ISO/IEC 15962的数据元素编码方案》

在这里插入图片描述

点击下载《C# 实现图书馆射频识别数据模型压缩算法(源代码+pdf参考资料)》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/285658.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何联合Qt,VS,C++,来开发一个电脑版软件(简单有趣,详细)

本教程适合 新手VS+QT小白。目前更新到了可以写一个计算器【拉到文章末尾,可以看到界面】。 前置安装 VS2019 或2022 社区版(这个太简单,就不在这里写了!)建议参考之前写的文章: https://zhuanlan.zhihu.com/p/682531067 注册登陆Qt账户 Try Qt 下载Qt 登陆之后,…

iOS开发 - 转源码 - __weak问题解决

iOS开发 - 转源码 - __weak问题解决 在使用clang转换OC为C代码时&#xff0c;可能会遇到以下问题 cannot create __weak reference in file using manual reference 原因 __weak弱引用是需要runtime支持的&#xff0c;如果我们还只是使用静态编译&#xff0c;是无法正常转换的…

Jenkins的快速入门

文章目录 一、Jenkins是什么&#xff1f;二、Jenkins安装和持续集成环境配置1.持续集成流程说明2.Gitlab代码托管服务器安装Gitlab简介&#xff1a;Gitlab安装Gitlab的使用切换中文添加组创建用户将用户添加到组创建项目idea中代码上传Gitlab 3.Jenkins持续集成环境服务器安装J…

在MongoDB建模1对N关系的基本方法

“我在 SQL 和规范化数据库方面拥有丰富的经验&#xff0c;但我只是 MongoDB 的初学者。如何建立一对 N 关系模型&#xff1f;” 这是我从参加 MongoDB 分享日活动的用户那里得到的最常见问题之一。 我对这个问题没有简短的答案&#xff0c;因为方法不只有一种&#xff0c;还有…

【Python实战】——神经网络识别手写数字

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

【C++从练气到飞升】05---运算符重载

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 ⛳️推荐 一、运算符重载的引用 二、运算符重载 三、赋值运算符重载 1 .赋值运算符重载格式: 2 .赋值运算符只能重载成…

SAP 标准委外业务对已收货后对组件的后续调整简介

标准委外业务对已收货后对组件的后续调整 通常在委外的业务中经常会存在发给供应商的物料发现有少发&#xff0c;或者需要补发的情况&#xff0c;委外的业务都是基于采购订单收货的时候才对供应商库存进行扣减。委外成品在收货后产生543的移动类型原材料进行冲消。 但是我们在物…

【C语言】编译和链接----预处理详解【图文详解】

欢迎来CILMY23的博客喔&#xff0c;本篇为【C语言】文件操作揭秘&#xff1a;C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】&#xff0c;感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言 欢迎来到本篇博客&…

继承和多态(2)(多态部分)

提前讲的重要知识点 一个类在没有父类的情况下默认有一个父类为Object类。 而当在有父类情况下&#xff0c;如果你那父类没有父类&#xff0c;则其父类的父类默认为object类&#xff0c;所以即使一个类有父类&#xff0c;其内部还是有object类。 object类都是隐藏起来的&…

【机器学习】基于北方苍鹰算法优化的BP神经网络分类预测(NGO-BP)

目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】北方苍鹰优化算法&#xff08;NGO)原理及实现 2.设计与实现 数据集&#xff1a; 数据集样本总数2000 多输入单输出&#xff1a;样本特征24&#x…

Vue3:网页项目中路由的设计和配置

为了避免我每次建项目配路由的时候都回去翻网课&#xff0c;打算整一博客 路由设计 不同网页的路由设计思路基本相同&#xff0c;分为一级路由和二级路由&#xff0c;基本设计思路如下图 以我之前做过的招新系统管理端为例&#xff0c;可设计出如下路由 路由配置 还是以招新系…

剖析美国政府视角下的ICT供应链安全

2018 年 11 月 15 日&#xff0c;美国国土安全部&#xff08;DHS&#xff09;宣布成立了信息和通信技术 (ICT) 供应链风险管理&#xff08;SCRM&#xff09;工作组&#xff0c;这个工作组是由美国多个政府部门、IT行业企业代表及通信行业企业代表联合成立的。该组织对外宣传的目…

Docker Command

小试牛刀 # 查看docker版本 docker -v docker --version # 查看帮助 docker --help # 永远的Hello World docker run hello-world镜像操作 查看本地已有的镜像 docker images -a :列出本地所有的镜像&#xff08;含中间映像层&#xff09; -q :只显示镜像ID --digests :显示…

C# 右键快捷菜单(上下文菜单)的两种实现方式

在C#中&#xff0c;ContextMenuStrip是一种用于创建右键菜单的控件。它提供了一种方便的方式来为特定的控件或窗体添加自定义的上下文菜单选项。有两种实现方式&#xff0c;如下&#xff1a; 一.通过ContextMenuStrip控件实现 1.从工具箱中拖一个ContextMenuStrip控件到窗体上…

Java面试题总结200道(四)

76、ApplicationContext 通常的实现是什么? FileSystemXmlApplicationContext &#xff1a;此容器从一个 XML 文件中加 载 beans 的定义&#xff0c;XML Bean 配置文件的全路径名必须提供给它的构造函数。ClassPathXmlApplicationContext&#xff1a;此容器也从一个 XML 文件…

python、execl数据分析(数据描述)

一 python 1.各函数 1.1python库的安装与导入 #pip install os#pip install matplotlib#pip install seaborn#pip install scikit-learn#pip install scipy#修 改 工 作 目 录import osos.getcwd () # 查看当前工作环境os.chdir( F :\my course\database ) # 修改工作环境o…

数据挖掘不是挖土豆,而是让数据开口说话!

文章目录 1、 缘起1.1 啤酒与尿布 - 发现商业价值1.2 数据挖掘 - 让数据说话 2、数据挖掘的难点3、数据挖掘的方法 Part 1 - 专业技术流3.1 网络数据采集 - 代理技术3.2 网络数据采集 - 爬虫浏览器3.3 网络数据采集 - 网络解锁器3.4 网络数据采集 - Web Scraper IDE 4、数据挖掘…

力扣100热题[哈希]:最长连续序列

原题&#xff1a;128. 最长连续序列 题解&#xff1a; 官方题解&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;题解&#xff0c;最长连续序列 &#xff1a;哈希表 官方解题思路是先去重&#xff0c;然后判断模板长度的数值是否存在&#xff0c;存在就刷新&#xff0c…

python类属性和global变量区别

数据成员是指在类中定义的变量&#xff0c;即属性&#xff0c;根据定义位置&#xff0c;又可以分为类属性和实例属性。 类属性定义在方法前面。 定义类属性&#xff0c;非全局变量 class MyClass:#global cc 10 ## 类属性def my_function(self):global qwqw 9print(this …

Vue项目使用process.env关键字及Vue.config.js配置解决前端跨域问题

1.process.env 是Node.js 中的一个环境 1.打开命令行查看环境: 2.process.env与Vue CLI 项目 Vue Cli 有以下三种运行模式 development 模式用于 vue-cli-service serve test 模式用于 vue-cli-service test:unit production 模式用于 vue-cli-service build 和 vue-cli-se…