我想我找到了解决方案。我不想简单地介绍解码算法,而是向您展示推理。
链接问题的答案表明这是EAN-13格式的条形码。
这意味着代码有 12 位和 1 个校验位:
11.11.2010 16:23 > 525242537257 5
16.11.2010 15:30 > 525292246256 4
19.11.2010 15:39 > 525223156251 1
19.11.2010 15:43 > 525223556250 0
校验位可由下式计算
- 将偶数位置的数字值相加:2、4、6 ... (2+2+2+3+2+7=18)
- 将此结果乘以 3 (18*3=54)
- 将奇数位的数字值相加:1、3、5... (5+5+4+5+7+5=31)
- 将两个结果相加 (54+31=85)
- 计算模 10 并从 10 中减去 (5-10=5)
我计算了每个代码的校验位,它匹配并确认代码是 EAN-13 格式。
根据规范,代码的前两位或三位可能是国家代码,所以我尝试将它们分开:
11.11.2010 16:23 > 52 5242537257 5 | 525 242537257 5
16.11.2010 15:30 > 52 5292246256 4 | 525 292246256 4
19.11.2010 15:39 > 52 5223156251 1 | 525 223156251 1
19.11.2010 15:43 > 52 5223556250 0 | 525 223556250 0
结果数字没有任何意义,因为较早的时间有更大的数字:
5292246256或292246256
比后来的时间:
5223156251或223156251
此时我怀疑时间不是以二进制格式存储的。我重新组织了数字并试图找到重复的模式。
我最终得到了这个布局:
11.11.2010 16:23 > 52 52 42 53 72 57 5
16.11.2010 15:30 > 52 52 92 24 62 56 4
19.11.2010 15:39 > 52 52 23 15 62 51 1
19.11.2010 15:43 > 52 52 23 55 62 50 0
这就是事情变得有趣的地方......
看一下第 3 行和第 4 行,除了第 4 列和第 6 列之外,它们是相同的。
第 4 列有15和55。将其向后翻译,您会得到51和55。
两者的差是55 - 51 = 4就像分钟的差43 - 39 = 4
从代码值中减去分钟:
55 - 43 = 12
51 - 39 = 12
似乎第 4 列通过添加 12 并将数字向后存储来对分钟进行编码。
现在尝试将此应用于第 5 列:
11.11.2010 16:23 > 72 > 27
16.11.2010 15:30 > 62 > 26
19.11.2010 15:39 > 62 > 26
19.11.2010 15:43 > 62 > 26
26 - 15 = 11和27 - 16 = 11所以第 5 列的差值为 11。
从那时起很容易,列的差异是 15、14、13、12 和 11。
一些快速计算,你得到编码方案:
Digits Meaning Diff.
2-1 year 15
4-3 month 14
6-5 day 13
8-7 minute 12
10-9 hour 11
这是一个简单的解码代码片段:
union TimeFormat
{
unsigned short codearray[5];
struct
{
unsigned short year;
unsigned short month;
unsigned short day;
unsigned short minute;
unsigned short hour;
};
};
void DecodeBarcode(char *code, TimeFormat *time)
{
char buf[3]; // for atoi()
buf[2] = 0; // of course it has to be null-terminated
for (int i = 0, diff = 15; i < 5; ++i, --diff)
{
buf[0] = code[i * 2 + 1];
buf[1] = code[i * 2];
time->codearray[i] = atoi(buf) - diff;
}
time->year += 2000;
}