通用产品代码 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
·编码
·解码
·模校验
·输出
·倒着读取的情况
·压缩
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