通用产品代码 UPC
来自于《编码》
几乎每件商品上都有所谓的条形码,即通用产品代码 UPC(Universal Product Code)。其可以标识该商品是哪个厂家生产的,并且是这个厂家的哪个商品。这里面并无价格信息,可以根据其所标识的代码去查询卖家的计算机系统得到其价格。
UPC 是有宽度各不相同的黑白条码组成,根据其宽度映射为一个二进制序列,总共有 95 位
从左到右依次是:
101 三位的最左边护线
7 * 6 四十二位的左边数字,7 位标识一个数字,总共有 6 个数字
01010 五位中间护线
7 * 6 四十二位的左边数字,7 为标识一个数字,总共有 6 个数字
101 三位的最右边护线
3 + 42 + 5 + 42 + 3,即 95 位 01 序列。
UPC 也可以反向扫描,这样增加了卖家售货员的操作便宜性,同时也对生产厂商灵活性也给大,只不过这种灵活性不应该利用。
可以反向扫描的原因在于,左右标识的 6 个数字编码不相同。
正向的情况:
左边数字编码如下:
0001101 = 0
0011001 = 1
0010011 = 2
0111101 = 3
0100011 = 4
0110001 = 5
0101111 = 6
0111011 = 7
0110111 = 8
0001011 = 9
左边数字编码如下:
1110010 = 0
1100110 = 1
1101100 = 2
1000010 = 3
1011100 = 4
1001110 = 5
1010000 = 6
1000100 = 7
1001000 = 8
1110100 = 9
从中我们可以看到左边数字的编码,都是 0 开头,1 结尾的。同时每个数字的 7 位编码中都是有奇数个 1 ,这是奇校验。
左边数字的编码,都是 1 开头,0 结尾的。同时每个数字的 7 为编码都是有偶数个 1 ,这是偶校验。
针对一个 UPC 进行扫描的时候,首先检查第一个数字编码是否符合奇校验,如果符合则其实正向读取的。如果符合偶校验,则是反向读取的。
左右个标识 6 个数字,总共 12 个数字 A BCDEF GHIJK L,其中
第一个数字标识该商品属于那种类别。
2 - 6 标识哪个制造商
7 - 11 标识制造商的哪个商品
最后一个数字是模校验字符。计算方式如下:L = 10 - (3 * (A + C + E + G + I + K) + (B + D F + H + J)) % 10;
这里要做的工作就是:
对通用产品代码 UPC
·编码
·解码
·模校验
·输出
·倒着读取的情况
·压缩
1 #include <iostream>
2 #include <string>
3 #include <map>
4 #include <algorithm>
5 using namespace std;
6
7 void init(map<char, string>& encoding_left, map<char, string>& encoding_right, map<string, char>& decoding)
8 {
9 encoding_left['0'] = "0001101";
10 encoding_left['1'] = "0011001";
11 encoding_left['2'] = "0010011";
12 encoding_left['3'] = "0111101";
13 encoding_left['4'] = "0100011";
14 encoding_left['5'] = "0110001";
15 encoding_left['6'] = "0101111";
16 encoding_left['7'] = "0111011";
17 encoding_left['8'] = "0110111";
18 encoding_left['9'] = "0001011";
19
20 encoding_right['0'] = "1110010";
21 encoding_right['1'] = "1100110";
22 encoding_right['2'] = "1101100";
23 encoding_right['3'] = "1000010";
24 encoding_right['4'] = "1011100";
25 encoding_right['5'] = "1001110";
26 encoding_right['6'] = "1010000";
27 encoding_right['7'] = "1000100";
28 encoding_right['8'] = "1001000";
29 encoding_right['9'] = "1110100";
30
31 decoding["0001101"] = '0';
32 decoding["0011001"] = '1';
33 decoding["0010011"] = '2';
34 decoding["0111101"] = '3';
35 decoding["0100011"] = '4';
36 decoding["0110001"] = '5';
37 decoding["0101111"] = '6';
38 decoding["0111011"] = '7';
39 decoding["0110111"] = '8';
40 decoding["0001011"] = '9';
41
42 decoding["1110010"] = '0';
43 decoding["1100110"] = '1';
44 decoding["1101100"] = '2';
45 decoding["1000010"] = '3';
46 decoding["1011100"] = '4';
47 decoding["1001110"] = '5';
48 decoding["1010000"] = '6';
49 decoding["1000100"] = '7';
50 decoding["1001000"] = '8';
51 decoding["1110100"] = '9';
52
53 decoding["0100111"] = '0';
54 decoding["0110011"] = '1';
55 decoding["0011011"] = '2';
56 decoding["0100001"] = '3';
57 decoding["0011101"] = '4';
58 decoding["0111001"] = '5';
59 decoding["0000101"] = '6';
60 decoding["0010001"] = '7';
61 decoding["0001001"] = '8';
62 decoding["0010111"] = '9';
63
64 decoding["1011000"] = '0';
65 decoding["1001100"] = '1';
66 decoding["1100100"] = '2';
67 decoding["1011110"] = '3';
68 decoding["1100010"] = '4';
69 decoding["1000110"] = '5';
70 decoding["1111010"] = '6';
71 decoding["1101110"] = '7';
72 decoding["1110110"] = '8';
73 decoding["1101000"] = '9';
74
75 //cout << encoding_left.size() << endl;
76 //cout << encoding_right.size() << endl;
77 //cout << decoding.size() << endl;
78 }
79
80 string dropSpaces(string& code)
81 {
82 string ret;
83 for (string::size_type i = 0; i != code.size(); ++i)
84 {
85 if (code[i] >= '0' && code[i] <= '9')
86 {
87 ret += code[i];
88 }
89 }
90 code = ret;
91 return ret;
92 }
93
94 string encode(const string& code_e, const map<char, string>& encoding_left, const map<char, string>& encoding_right)
95 {
96 string code = code_e;
97 dropSpaces(code);
98 if (code.size() != 11)
99 {
100 return "Error!";
101 }
102 string ret;
103
104 ret += "101";
105 for (string::size_type i = 0; i != 6; ++i)
106 {
107 map<char, string>::const_iterator cit = encoding_left.find(code[i]);
108 if (cit != encoding_left.end())
109 {
110 ret += cit->second;
111 }
112 else
113 {
114 return "Error!";
115 }
116 }
117 ret += "01010";
118 for (string::size_type i = 6; i != code.size(); ++i)
119 {
120 map<char, string>::const_iterator cit = encoding_right.find(code[i]);
121 if (cit != encoding_right.end())
122 {
123 ret += cit->second;
124 }
125 else
126 {
127 return "Error!";
128 }
129 }
130
131 int x = 0;
132 for (string::size_type i = 0; i < code.size(); i += 2)
133 {
134 x += (code[i] - '0');
135 }
136 x *= 3;
137 for (string::size_type i = 1; i < code.size(); i += 2)
138 {
139 x += (code[i] - '0');
140 }
141 x = 10 - x % 10;
142 map<char, string>::const_iterator cit = encoding_right.find(x + '0');
143 if (cit != encoding_right.end())
144 {
145 ret += cit->second;
146 }
147 else
148 {
149 return "Error!";
150 }
151
152 ret += "101";
153 return ret;
154 }
155
156 string decode(const string& eode, map<string, char>& decoding)
157 {
158 if (eode.size() != 95)
159 {
160 return "Error!";
161 }
162 string ret;
163 string t = eode.substr(3, 7);
164 bool f = true;
165 for (string::size_type i = 0; i != t.size(); ++i)
166 {
167 if (t[i] == '1')
168 {
169 f = !f;
170 }
171 }
172 for (int i = 0; i != 6; ++i)
173 {
174 string tmp = eode.substr(3 + 7 * i, 7);
175 map<string, char>::const_iterator cit = decoding.find(tmp);
176 if (cit != decoding.end())
177 {
178 ret += cit->second;
179 }
180 else
181 {
182 return "Error!";
183 }
184 }
185 for (int i = 0; i != 6; ++i)
186 {
187 string tmp = eode.substr(50 + 7 * i, 7);
188 map<string, char>::const_iterator cit = decoding.find(tmp);
189 if (cit != decoding.end())
190 {
191 ret += cit->second;
192 }
193 else
194 {
195 return "Error!";
196 }
197 }
198 if (f)
199 {
200 reverse(ret.begin(), ret.end());
201 }
202 ret = ret.substr(0, 1) + " " + ret.substr(1, 5) + " " + ret.substr(6, 5) + " " + ret.substr(11, 1);
203 return ret;
204 }
205
206 string compress(const string& eode)
207 {
208 string ret;
209 return ret;
210 }
211
212 void display(const string& eode)
213 {
214 string tmp;
215 for (string::size_type i = 0; i != 70; ++i)
216 {
217 if (eode[i] == '0')
218 {
219 tmp += ' ';
220 }
221 else
222 {
223 tmp += '@';
224 }
225 }
226 tmp += '\n';
227 for (int i = 0; i != 10; ++i)
228 {
229 cout << tmp << endl;
230 }
231 }
232
233 int main()
234 {
235 map<char, string> encoding_left, encoding_right;
236 map<string, char> decoding;
237 init(encoding_left, encoding_right, decoding);
238 string code;
239 while (getline(cin, code))
240 {
241 string eode = encode(code, encoding_left, encoding_right);
242
243 cout << code << endl;
244 cout << eode << endl;
245 cout << eode.size() << endl;
246
247 display(eode);
248 reverse(eode.begin(), eode.end());
249
250 code = decode(eode, decoding);
251 cout << code << endl;
252 cout << code.size() << endl;
253 }
254 }
255
posted on 2011-11-18 11:14
unixfy 阅读(740)
评论(0) 编辑 收藏 引用