39801


与えられた文字列について、UTF-8に定義されているがShiftJIS（正確にはCP932）に定義されていない文字があるかどうか検出する方法はありますか？  
文字コードの変換のやり方は結構見つかりますが、ちゃんと変換できたのかどうかを判定したいのです。  
※ShiftJISしか使えない旧システムとの連携があるため、「旧システムに渡せない文字」をユーザが入力したとき、弾けるように・・・  
Java8を使っています。


CC BY-SA 3.0
2017-11-24T02:36:38.723
39795
2018-01-26T18:23:11.147
2017-11-24T05:37:03.510
8078
8078
question
java
ShiftJISに無い文字を検出する方法


UTF-8の入力文字列(Java内部ではUnicode)をCP932バイト列に変換して、それを再度UTF-8に変換(逆変換)して、同じ内容にならなければ、その差分が定義されていない文字と判定する方法があると思います。

＃変換中にExceptionが発生すれば、その時点で定義されていない文字が含まれていることがわかります。

ただ、「旧システム」がCP932文字ならすべて受け取れるのか怪しいので、通常は流通可能な文字集合(ホワイトリスト)を規定して、入力文字(を変換したもの)をホワイトリストと比較する方法の方が確実かと思います。


CC BY-SA 3.0
2017-11-24T06:48:13.277
39801
2017-11-24T06:48:13.277
20098
39795
answer


「文字列`s`がCP932（`MS932`）に変換できるかを調べる」ためのコード：

[code]

    if (Charset.forName("MS932").newEncoder().canEncode(s)) {
        // 変換可能
    } else {
        // 変換不能
    }
    
[/code]

「文字列`s`をCP932（`MS932`）のバイト列に変換する、ただし変換不能ならその旨を伝える」ためのコード：

[code]

    try {
        ByteBuffer bb = Charset.forName("MS932").newEncoder()
                .onUnmappableCharacter(CodingErrorAction.REPORT)
                .encode(CharBuffer.wrap(s)); // ByteBufferを得る
        byte[] ba = bb.array(); // byte配列を得る
    } catch(CharacterCodingException e) {
        // 変換不能だった
    }
    
[/code]

※「変換可能」とは「`String#getBytes()`で正常に（`?`に化けずに）変換可能」を指します。


CC BY-SA 3.0
2018-01-26T18:23:11.147
41232
2018-01-26T18:23:11.147
27076
39795
answer