Shift-JIS字符集判断

    最近因为项目需要写了一段Shift-JIS字符集判断的函数。

    背景: 从AD Server读取用户信息,然后要写到Server上的文件系统,但是在Linux Server上老是出现乱码问题。字符变成了问号。而Windows Server上却没有这样的问题。

    后来发现Windows和Linux所使用的字符编码不一样。Linux使用的字符编码是Shift-JIS,而Windows使用的是MS932。因此有些字符在Linux上是不可能显示出来的。比如说⑨。

    鬼子要求写一个判断机能,防止使用shift-jis意外的字符。

    程序如下:

   public static boolean isShiftJIS(String dn){
        if (null == dn) {
            return false;
        }
       
        for (int i = 0; i < dn.length(); i++) {
            char c = dn.charAt(i);
            byte[] b = new byte[0];
            try {
                b = Character.toString(c).getBytes("Shift_JIS");
            } catch (Exception e) {
                e.printStackTrace();
            }

            // Shift-JISの1バイトコード(半角文字)のエリア
            if (b.length == 1) {
                int firstByte = b[0];
                if (firstByte < 0) {
                    firstByte += 256;
                }

                // 0x00~0x1F、0x7F は制御コードです
                if ((0x00 <= firstByte && firstByte <= 0x1F) || firstByte == 0x7F) {
                    return false;
                }
                // 0x20~0x7E はASCII文字です
                else if (0x20 <= firstByte && firstByte <= 0x7E) {
                    //Unicode -> Shift-Jisの場合、非Shift-JIS文字が[?]に変化
                    if (firstByte != c) {
                        return false;
                    }
                    continue;
                }
                // 0xA1~0xDF は半角カタカナです
                else if (0xA1 <= firstByte && firstByte <= 0xDF) {
                    continue;
                }
                // Shift-JIS以下の文字
                else {
                    return false;
                }
            }
            // シフトJISの2バイトコード(全角文字)のエリア(JIS X 0208の漢字エリア)
            else if (b.length == 2) {
                int firstByte = b[0];
                int secondByte = b[1];

                if (firstByte < 0) {
                    firstByte += 256;
                }

                if (secondByte < 0) {
                    secondByte += 256;
                }

                // 上位1バイト0x81~0x9F、 0xE0~0xEF
                // 下位1バイト0x40~0x7E、 0x80~0xFC
                if ((0x81 <= firstByte && firstByte <= 0x9F || 0xE0 <= firstByte && firstByte <= 0xEF)
                        && (0x40 <= secondByte && secondByte <= 0x7E || 0x80 <= secondByte && secondByte <= 0xFC)) {
                    String sHex = Integer.toHexString(firstByte) + Integer.toHexString(secondByte);
                    int code = Integer.parseInt(sHex, 16);
                    if(0x81AD<=code && code<=0x81B7
                            || 0x81C0<=code && code<=0x81C7
                            || 0x81CF<=code && code<=0x81D9
                            || 0x81E9<=code && code<=0x81EF
                            || 0x81F8<=code && code<=0x81FC
                            || 0x8240<=code && code<=0x824e
                            || 0x8259<=code && code<=0x825f
                            || 0x827A<=code && code<=0x8280
                            || 0x829B<=code && code<=0x829E
                            || 0x82F2<=code && code<=0x82FC
                            || 0x8397<=code && code<=0x839E
                            || 0x83B7<=code && code<=0x83BE
                            || 0x83D7<=code && code<=0x83FC
                            || 0x8461<=code && code<=0x846F
                            || 0x8492<=code && code<=0x849E
                            || 0x84BF<=code && code<=0x84FC
                            || 0x8540<=code && code<=0x889E
                            || 0x9873<=code && code<=0x989E
                            || 0xEBA5<=code && code<=0xEBFC
                            || 0xEB40<=code && code<=0xEFFC){
                        return false;
                    }
                } else {
                    return false;
                }
            }else{
                return false;
            }
        }
        return true;
    }

 

说明:

文字编码表(Shift_JIS)

Shift-JIS的1字节编码(半角文字)的区域
    * 0x00~0x1f、0x7f是控制字符
    * 0x20~0x7e 是ASCII文字
    * 0xa1~0xdf 是半角カタカナ

Shift-JIS的2字节编码(全角文字)的区域(JIS X 0208的汉字区域)
   * 高字节:0x81~0x9f、 0xe0~0xef

    * 低字节:0x40~0x7e、 0x80~0xfc

下面表中,浅蓝色的部分是非Shift-JIS字符。

 

Shift-JIS为1个字节的场合


16進数
2 進数
下 位 4 ビ ッ ト
0
0000
1
0001
2
0010
3
0011
4
0100
5
0101
6
0110
7
0111
8
1000
9
1001
a
1010
b
1011
c
1100
d
1101
e
1110
f
1111


0
0000
0
NUL
1
SOH
2
STX
3
ETX
4
EOT
5
ENQ
6
ACK
7
BEL
8
BS
9
HT
10
LF
11
VT
12
FF
13
CR
14
SO
15
SI
1
0001
16
DLE
17
DC1
18
DC2
19
DC3
20
DC4
21
NAK
22
SYN
23
ETB
24
CAN
25
EM
26
SUB
27
ESC
28
FS
29
GS
30
RS
31
US
2
0010
32
SP
33
!
34
"
35
#
36
$
37
%
38
&
39
'
40
(
41
)
42
*
43
+
44
,
45
-
46
.
47
/
3
0011
48
0
49
1
50
2
51
3
52
4
53
5
54
6
55
7
56
8
57
9
58
:
59
;
60
<
61
=
62
>
63
?
4
0100
64
@
65
A
66
B
67
C
68
D
69
E
70
F
71
G
72
H
73
I
74
J
75
K
76
L
77
M
78
N
79
O
5
0101
80
P
81
Q
82
R
83
S
84
T
85
U
86
V
87
W
88
X
89
Y
90
Z
91
[
92
/
93
]
94
^
95
_
6
0110
96
`
97
a
98
b
99
c
100
d
101
e
102
f
103
g
104
h
105
i
106
j
107
k
108
l
109
m
110
n
111
o
7
0111
112
p
113
q
114
r
115
s
116
t
117
u
118
v
119
w
120
x
121
y
122
z
123
{
124
|
125
}
126
~
127
DEL
8
1000
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
9
1001
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
a
1010
160 161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
b
1011
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
ソ
c
1100
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
d
1101
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
e
1110
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
f
1111
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

 

Shift-JIS为2个字节的场合

0102030405060708091011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939401020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
16進404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc
01/0281 ´¨_±× ÷°§
03/0482
05/0683 ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω
07/0884АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмн опрстуфхцчшщъыьэюя
09/1085
11/1286
13/1487
15/1688
17/1889 沿
19/208a 橿竿
21/228b
23/248c
25/268d稿
27/288e使姿 鹿湿寿
29/308f宿駿
31/3290 西穿
33/3491 退
35/3692辿 調椿
37/3893殿 禿廿
39/4094尿
41/4295 便簿
43/4496貿 麿婿綿
45/4697輿耀
47/4898 丿
49/5099
51/529a
53/549b 广
55/569c彿忿
57/589d
59/609e 榿槿
61/629f歿 滿漿
a0
a1
a2
a3
a4
a5
a6
a7
a8
a9
aa
ab
ac
ad
ae
af
b0
b1
b2
b3
b4
b5
b6
b7
b8
b9
ba
bb
bc
bd
be
bf
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9
ca
cb
cc
cd
ce
cf
d0
d1
d2
d3
d4
d5
d6
d7
d8
d9
da
db
dc
dd
de
df
63/64e0
65/66e1
67/68e2祿 窿
69/70e3紿 繿
71/72e4
73/74e5
75/76e6覿 谿跿
77/78e7
79/80e8
81/82e9 鴿
83/84ea
85/86eb
87/88ec
89/90ed俿 氿 溿
91/92ee 譿
93/94ef
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值