您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ArtcDataUtil.js 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /**
  2. * number转换成指定字节数的hexString
  3. * num:转换的number值
  4. * bitNum:转换后的字节数
  5. * isBig:true-大端,fasle-小端
  6. */
  7. var num2hex = function (num, bitNum, isBig) {
  8. //转大端hex并补足
  9. let hex = num.toString(16);
  10. for (let i = hex.length; i < bitNum * 2; i++) {
  11. hex = "0" + hex;
  12. }
  13. //多位截取
  14. if (hex.length > bitNum * 2) {
  15. hex = hex.substring(hex.length - bitNum * 2);
  16. }
  17. //转小端
  18. if (isBig == false) {
  19. let temp = "";
  20. for (let i = hex.length - 2; i >= 0; i -= 2) {
  21. temp = temp + hex.substring(i, i + 2);
  22. }
  23. hex = temp;
  24. }
  25. return hex;
  26. }
  27. /**
  28. * 将hexString转成bufferArray
  29. */
  30. var hex2buf = function (hexString) {
  31. let bufferArray = new Uint8Array(hexString.match(/[\da-f]{2}/gi).map(function (h) {
  32. return parseInt(h, 16)
  33. }))
  34. return bufferArray.buffer
  35. }
  36. /**
  37. * 将bufferArray转成hexString
  38. */
  39. var buf2hex = function (bufferArray) {
  40. let hex = Array.prototype.map.call(new Uint8Array(bufferArray), x => ('00' + x.toString(16)).slice(-2)).join('')
  41. return hex
  42. }
  43. /**
  44. * TLV指令构造
  45. * tpdus:指令集合
  46. * needResponse:对于tpdu指令是否需要返回数据,true有返回,fasle没有返回,如:["00a40000023f00","00a40000021001"],[true,false],这前一条有返回3f00的信息和状态码,后一条则只返回状态码,没有信息
  47. */
  48. var makeTLV = function (tpdus, needResponses) {
  49. let tlv = ""
  50. for (let i = 0; i < tpdus.length; i++) {
  51. let temp = "" + tpdus[i]
  52. let status = i + 1
  53. if (typeof needResponses == "object" && needResponses[i] === false) {
  54. status = 0x80 + status
  55. }
  56. //指令失败继续往下执行
  57. status += 0x40;
  58. let cmdLen = parseInt(temp.length / 2);
  59. let cmdLenHex = cmdLen.toString(16);
  60. if (cmdLenHex.length % 2 != 0) {
  61. cmdLenHex = "0" + cmdLenHex;
  62. }
  63. if (cmdLen > 0x80) {
  64. cmdLenHex = (0x80 + parseInt(cmdLenHex.length / 2)).toString(16) + cmdLenHex;
  65. }
  66. tlv = tlv + num2hex(status, 1, true) + cmdLenHex + temp;
  67. }
  68. let tlvLen = tlv.length / 2;
  69. let tlvLenHex = tlvLen.toString(16);
  70. if (tlvLenHex.length % 2 != 0) {
  71. tlvLenHex = "0" + tlvLenHex;
  72. }
  73. if (tlvLen > 0x80) {
  74. tlvLenHex = (0x80 + parseInt(tlvLenHex.length / 2)).toString(16) + tlvLenHex;
  75. }
  76. return "80" + tlvLenHex + tlv;
  77. }
  78. /**
  79. * 分解TLV指令结构,返回tpdu指令数组
  80. */
  81. var reTLV = function (tlv) {
  82. let tpdus = new Array();
  83. let lenc = parseInt(tlv.substring(2, 4), 16);
  84. let index = 4;
  85. if (lenc > 0x80) {
  86. index = index + (lenc - 0x80) * 2;
  87. }
  88. let count = 1;
  89. while (index < tlv.length) {
  90. let time = parseInt(tlv.substring(index, index + 2), 16);
  91. index += 2;
  92. let len = parseInt(tlv.substring(index, index + 2), 16);
  93. index += 2;
  94. if (len > 0x80) {
  95. let bit = (len - 0x80) * 2;
  96. len = parseInt(tlv.substring(index, index + bit), 16);
  97. index += bit;
  98. }
  99. let tpdu = tlv.substring(index, index + len * 2);
  100. tpdus.push(tpdu);
  101. index += len * 2;
  102. }
  103. if (tpdus.length == 0) {
  104. tpdus.push("FFFF");
  105. }
  106. return tpdus;
  107. }
  108. const frame_Len = 184
  109. const send_Len = 40
  110. const ST = "50"
  111. var makeFrame = function (data) {
  112. let frameCount = parseInt(data.length / frame_Len)
  113. let frameBalance = data.length % frame_Len
  114. let frames = new Array()
  115. for (let i = 0; i < frameCount; i++) {
  116. frames.push(data.slice(i * frame_Len, (i + 1) * frame_Len))
  117. }
  118. if (frameBalance > 0) {
  119. frames.push(data.slice(- frameBalance))
  120. }
  121. //加厂商结构
  122. let manufacturerFrames = new Array();
  123. for (let i = 0; i < frames.length; i++) {
  124. let temp = frames[i]
  125. let CTL = ""
  126. if (i == 0) {
  127. CTL = num2hex(0x8000 + frames.length, 2, true)
  128. }
  129. else {
  130. CTL = num2hex(i + 1, 2, true)
  131. }
  132. let LEN = num2hex(parseInt(temp.length / 2), 1, true)
  133. let frame = ST + CTL + LEN + temp
  134. let bcc = 0
  135. for (let j = 0; j < parseInt(frame.length / 2); j++) {
  136. let bit = parseInt(frame.slice(j * 2, (j + 1) * 2), 16)
  137. bcc = bcc ^ bit
  138. }
  139. frame += num2hex(bcc, 1, true)
  140. manufacturerFrames.push(frame)
  141. }
  142. //分割发生小包
  143. let bufferArray = new Array()
  144. for (let i = 0; i < manufacturerFrames.length; i++) {
  145. let temp = manufacturerFrames[i]
  146. let bufferCount = parseInt(temp.length / send_Len)
  147. let bufferBalance = temp.length % send_Len
  148. for (let j = 0; j < bufferCount; j++) {
  149. let item = temp.slice(j * send_Len, (j + 1) * send_Len)
  150. bufferArray.push(hex2buf(item))
  151. }
  152. if (bufferBalance > 0) {
  153. let item = temp.slice(- bufferBalance)
  154. bufferArray.push(hex2buf(item))
  155. }
  156. }
  157. return bufferArray
  158. }
  159. /**
  160. * 设备初始化通道
  161. */
  162. var make80SendData = function () {
  163. let data = "80"
  164. return makeFrame(data)
  165. }
  166. /**
  167. * 对设备操作通道
  168. * "c0" : 获取设备的设备表面号
  169. * "c1" : 获取设备的版本号
  170. * "c2" : 获取设备的电池电量
  171. * "c3" : 强制设备断电
  172. * "c4" : 对设备复位
  173. * "c5" : 获取设备的蓝牙MAC
  174. * "cc" : 获取设备信息:ASCII码,最长100字节
  175. */
  176. var make81SendData = function (command) {
  177. let data = "81"
  178. let len = num2hex(parseInt(command.length / 2), 2, false)
  179. data += len
  180. data += command
  181. return makeFrame(data)
  182. }
  183. /**
  184. * 对IC/ESAM/SE等进行COS操作通道
  185. * dataType : bit0=数据类型(0-明文数据,1-密文数据);bit1~bit3=(设置为0);bit4~bit7=目标索引(1-用户卡,2-ESAM安全模块,3-SE,其他保留)
  186. * cos : TLV格式(长度不超过384)
  187. */
  188. var make82SendData = function (dataType, cos) {
  189. let data = "82"
  190. let len = num2hex(parseInt(cos.length / 2), 2, false)
  191. data += dataType
  192. data += len
  193. data += cos
  194. return makeFrame(data)
  195. }
  196. /**
  197. * 获取IC卡密文通讯时的记录通道
  198. * conmand : "co" + 记录索引
  199. */
  200. var make83SendData = function (command) {
  201. let data = "83"
  202. let len = num2hex(parseInt(command.length / 2), 2, false)
  203. data += len
  204. data += command
  205. return makeFrame(data)
  206. }
  207. /**
  208. * 设备认证(包括更新终端证书)操作通道
  209. * "c0" : 设备认证步骤1
  210. * "c1" + 工作密钥密文 + ... + Rnd2 + S2 : 设备认证步骤2
  211. * "c2" : 更新终端证书步骤1 -- 初始化
  212. * "c3" : 更新终端证书步骤2 -- 获取终端公钥
  213. * "c4" + 终端证书 : 更新终端证书步骤3 -- 更新证书
  214. */
  215. var make84SendData = function (command) {
  216. let data = "84"
  217. let len = num2hex(parseInt(command.length / 2), 2, false)
  218. data += len
  219. data += command
  220. return makeFrame(data)
  221. }
  222. /**
  223. * 数据透彻操作通道
  224. * dataType : bit0=数据类型(0-明文数据,1-密文数据);bit1~bit3=(设置为0);bit4~bit7=目标索引(1-用户卡,2-ESAM安全模块,3-SE,其他保留)
  225. * command : 透彻指令数据
  226. */
  227. var make85SendData = function (dataType, command) {
  228. let data = "85"
  229. let len = num2hex(parseInt(command.length / 2), 2, false)
  230. data += dataType
  231. data += len
  232. data += command
  233. return makeFrame(data)
  234. }
  235. /**
  236. * 厂商自定义功能
  237. * "c1" + code : 设备显示字符,code("01"=激活中,"02"=激活成功,"03"=激活失败,"04"=发行中,"05"=发行成功,"06"=发行失败)
  238. */
  239. var make8FSendData = function (command) {
  240. let data = "8F"
  241. let len = num2hex(parseInt(command.length / 2), 2, false)
  242. data += len
  243. data += command
  244. return makeFrame(data)
  245. }
  246. var ArtcDataUtil = {
  247. num2hex: num2hex,
  248. hex2buf: hex2buf,
  249. buf2hex: buf2hex,
  250. makeTLV: makeTLV,
  251. reTLV: reTLV,
  252. make80SendData: make80SendData,
  253. make81SendData: make81SendData,
  254. make82SendData: make82SendData,
  255. make83SendData: make83SendData,
  256. make84SendData: make84SendData,
  257. make85SendData: make85SendData,
  258. make8FSendData: make8FSendData,
  259. }
  260. module.exports = ArtcDataUtil