215 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "coder_lib.h"
 | ||
| #include "string.h"
 | ||
| #include "mystring.h"
 | ||
| #include "crc.h"
 | ||
| #include "stdio.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--;
 | ||
|   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);
 | ||
|   
 | ||
|   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(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;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | 
