#include "coder_lib.h" #include "string.h" #include "elec/mystring.h" #include "stdio.h" #include "base/crc.h" /* +-----------------------------------------------------------------------+ | 管壳码格式(ascii) | +-----------------------------------------------------------------------+ | 13byte | +-----------------------------------------------------------------------+ | 雷管厂代号 | 生产年份 | 生产月份 | 生产日 | 特征号 | 流水号 | +------------+------------+------------+----------+----------+----------+ | 2byte | 1byte | 2byte | 2byte | 1byte | 5byte | +-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+ | UID码格式(ascii) | +-----------------------------------------------------------------------+ | 16byte | +-----------------------------------------------------------------------+ | 芯片厂代号 | 生产年份 | 雷管厂代号 | 月 | 日 | 特征码 | 盒号 | 序号 | +------------+----------+------------+-----+-----+--------+------+------+ | 2byte | 2byte | 2byte |2byte|2byte| 1byte | 3byte| 2byte| +-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+ | UID码存储格式(hex) | +-----------------------------------------------------------------------+ | 8byte | +-----------------------------------------------------------------------+ | 芯片厂代号 | 雷管厂代号 | 年月日 | 特征码盒号序号 | crc8 | +------------+------------+------------------+-------------------+------+ | 1byte | 1byte | 2byte(大端) | 3byte(大端) | 1byte| +-----------------------------------------------------------------------+ 年月日(ascii)->年月日(hex) 年(y),月(m),日(d) time=((((y[0]-'0')*10)+(y[1]-'0'))<<9)|\ ((((m[0]-'0')*10)+(m[1]-'0'))<<5)|\ (((d[0]-'0')*10)+(d[1]-'0')) 特征码盒号序号(ascii)->特征码盒号序号(hex) 特征码(c),盒号(b),序号(i) code=c*10000+((b[0]-'0')*100+(b[1]-'0')*10+(b[2]-'0'))*100+\ ((i[1]-'0')*10+(i[2]-'0')) */ // 根据管壳码和年份信息生成uid的年份信息 static int coder_calc_year(const char *year,const char shell_year,char *uid_year) { int y=0; for(int i=0;i<4;i++) { y*=10;y+=year[i]-'0'; } // year是实时数据,鉴于12月31生产的雷管,year可能不同 // 此时year-1来保证与uid码上的相同 // if(year[3]!=shell_year) // y--; for(int i=0;i<10;i++){ if((y%10)!=(shell_year-'0')) y--; else break; } uid_year[0]=y%100/10+'0'; uid_year[1]=y%10+'0'; if(uid_year[1]==shell_year) return 0; else return -1; } // 返回1则shell_code有效 int check_shell_code(const char *shell_code) { for(int i=0;i<13;i++) { if(shell_code[i]==0) return 0; } if(strncmp("0000000000000",shell_code,13)==0) return 0; return 1; } // 管壳码转uid码 int coder_shell_to_uid(const char *year,const char *shell_code,char *uid_code) { int ret=0; memset(uid_code,0,16); // 添加芯片企业代号(2byte) memcpy(&uid_code[0],"AD",2); // 添加年份(2y=byte) ret=coder_calc_year(year,shell_code[2],&uid_code[2]); // 添加雷管厂代号(2byte) memcpy(&uid_code[4],&shell_code[0],2); // 添加月日特征码流水号 memcpy(&uid_code[6], &shell_code[3],10); if(ret){ memset(uid_code,0,16); } return ret; } // JQ管壳码转uid码 int coder_shell_to_uid_jq(const char *year,const char *shell_code,char *uid_code) { int ret=0; memset(uid_code,0,16); // 添加雷管厂代号(2byte) memcpy(&uid_code[0],&shell_code[0],2); // 添加年份(2y=byte) ret=coder_calc_year(year,shell_code[2],&uid_code[2]); // 添加0(1byte) memcpy(&uid_code[4],"0",1); // 添加月日特征码流水号 memcpy(&uid_code[5], &shell_code[3],10); if(ret){ memset(uid_code,0,16); } return ret; } // 转换hex字符串为一个byte static int coder_strhex_to_byte(const char *str_hex) { char buff[3]={0}; buff[0]=str_hex[0]; buff[1]=str_hex[1]; return str_ahextoi(buff); } // 转换int字符串为一个整形 static int coder_strint_to_byte(const char *str_int,int len) { char buff[10]={0}; if(len>10) return 0; memcpy(buff,str_int,len); return str_atoi(buff); } // uid码转存储码 int coder_uid_to_save(const char *uid_code,uint8_t *save_code) { uint16_t ymd=0; uint32_t feature=0; save_code[0]=coder_strhex_to_byte(&uid_code[0]); save_code[1]=coder_strhex_to_byte(&uid_code[4]); ymd=coder_strint_to_byte(&uid_code[2],2)<<9; ymd|=coder_strint_to_byte(&uid_code[6],2)<<5; ymd|=coder_strint_to_byte(&uid_code[8],2); save_code[2]=ymd>>8; save_code[3]=ymd&0xff; // 文档 YM-UID设计V1.2 - 2023.xlsx 规定*10000,实际是*100000 feature=uid_code[10]*100000; feature+=coder_strint_to_byte(&uid_code[11],3)*100; feature+=coder_strint_to_byte(&uid_code[14],2); save_code[4]=feature>>16; save_code[5]=feature>>8; save_code[6]=feature&0xff; save_code[7]=crc::crc8(save_code,7); return 0; } // 转换byte为hex字符串 static int coder_byte_to_strhex(const uint8_t byte,char *str_hex) { char buff[10]={0}; sprintf(buff,"%02X",byte); str_hex[0]=buff[0]; str_hex[1]=buff[1]; return 0; } // 转换int为int字符串 static int coder_int_to_strint(const int n,char *str_int,int len) { char buff[10]={0}; sprintf(buff,"%05d",n); memcpy(str_int,buff+(strlen(buff)-len),len); return 0; } // 存储码转uid int coder_save_to_uid(const uint8_t *save_code,char *uid_code) { uint16_t ymd=0; uint32_t feature=0; int ret=0; if(save_code[7]!=crc::crc8((uint8_t *)save_code,7)) { return -1; } ret|=coder_byte_to_strhex(save_code[0],&uid_code[0]); ret|=coder_byte_to_strhex(save_code[1],&uid_code[4]); ymd=(save_code[2]<<8)|save_code[3]; feature=(save_code[4]<<16)|(save_code[5]<<8)|(save_code[6]); ret|=coder_int_to_strint(ymd>>9,&uid_code[2],2); ret|=coder_int_to_strint((ymd>>5)&0x0f,&uid_code[6],2); ret|=coder_int_to_strint((ymd)&0x1f,&uid_code[8],2); uid_code[10]=feature/100000; ret|=coder_int_to_strint(feature%100000/100,&uid_code[11],3); ret|=coder_int_to_strint(feature%100,&uid_code[14],2); return ret; } // uid码转管壳码 int coder_uid_to_shell(const char *uid_code,char *shell_code) { memset(shell_code,0,13); // 添加雷管厂代号 memcpy(&shell_code[0],&uid_code[4],2); // 添加生产年份 memcpy(&shell_code[2],&uid_code[3],1); // 添加月日特征码流水号 memcpy(&shell_code[3],&uid_code[6],10); return 0; }