2

ファイルの解釈に問題があります。ファイルは次のように構築されます。

「名前」-@-「日付」-@-「著者」-@-「署名」

署名はバイト配列です。ファイルを読み返すと、それを文字列に解析して分割します。

myFileInpuStream.read(fileContent);    
String[] data = new String(fileContent).split("-@-");

var fileContent を見ると、バイトが適切であることがわかります。しかし、署名バイト配列を取得しようとすると:

byte[] signature=  data[3].getBytes();

63 の値が間違っている場合があります。次の方法でいくつかの解決策を試しました。

new String(fileContent, "UTF-8")

しかし、運がありません。誰か助けてくれませんか?署名は固定長ではないため、ハードコードすることはできません...

追加情報:

元の署名:

[48, 45, 2, 21, 0, -123, -3, -5, -115 , 84, -86, 26, -124, -112, 75, -10, -1, -56, 40, 13 , -46, 6, 120, -56, 100, 2, 20, 66, -92, -8, 48, -88, 101, 57, 56, 20, 125, -32, -49, -123, 73 、96、76、-82、81、51、69]

filecontent(読み取り後の変数):

... 48, 45, 2, 21, 0, -123, -3, -5, -115 , 84, -86, 26, -124, -112, 75, -10, -1, -56, 40 、13、-46、6、120、-56、100、2、20、66、-92、-8、48、-88、101、57、56、20、125、-32、-49、-123 、73、96、76、-82、81、51、69]

署名 (分割および getBytes() 後):

[48, 45, 2, 21, 0, -123, -3, -5, 63 , 84, -86, 26, -124, 63, 75, -10, -1, -56, 40, 13, - 46, 6, 120, -56, 100, 2, 20, 66, -92, -8, 48, -88, 101, 57, 56, 20, 125, -32, -49, -123, 73, 96 、76、-82、81、51、69]

4

4 に答える 4

3

テーブルdata[4]に 4 つあるため、アクセスできません。したがって、0 から 3 までStringアクセスできます。data

data[0] = name

data[1] = date

data[2] = author

data[3] = signature

ソリューション :

byte[] signature = data[3].getBytes();
于 2013-03-19T13:21:07.987 に答える
1

編集:あなたが何をしているのか、ようやく理解できたと思います。

名前、日付、作成者、署名の 4 つの部分があります。名前と作成者は文字列、日付は日付、署名はハッシュまたは暗号化されたバイト配列です。で区切られたテキストとしてファイルに保存します-@-。これを行うには、まずそれぞれを有効な文字列に変換する必要があります。名前と作者はすでに文字列です。日付を文字列に変換するのは簡単です。バイト配列を文字列に変換するのは簡単ではありません。

base64エンコーディングを使用して、バイト配列を文字列に変換できます。javax.xml.bind.DatatypeConverter printBase64Binary()エンコードとjavax.xml.bind.DatatypeConverter parseBase64Binary()デコードに使用します。

たとえば、 name denBelg、 date 2013-03-19、 author Virtlink、およびこの署名がある場合:

30 2D 02 15 00 85 FD FB 8D 54 AA 1A 84 90 4B F6 FF C8 28 0D D2 06 78 C8 64 02 14
 42 A4 F8 30 A8 65 39 38 14 7D E0 CF 85 49 60 4C AE 51 33 45

次に、署名の連結と base64 エンコードの後、結果の文字列は次のようになります。

denBelg-@-20130319-@-Virtlink-@-MC0CFQCF/fuNVKoahJBL9v/IKA3SBnjIZAIUQqT4MKhlOTgUfeDPhUlgTK5RM0U=

後で文字列を分割-@-すると、base64 署名部分をデコードしてバイト配列を取得できます。

名前または作成が名前に含まれる可能性がある場合、-@-コードが台無しになる可能性があることに注意してください。たとえば、名前を次のように設定den-@-Belgすると、コードは失敗します。


元の投稿:

JavaString.getBytes()は、文字列にプラットフォームのデフォルトのエンコーディングを使用します。エンコーディングは、文字列文字をバイト値にマップする方法です。そのため、プラットフォームによっては、結果のバイトが異なる場合があります。

エンコーディングを修正UTF-8して同じエンコーディングで読むと、問題は解決します。

byte[] signature = data[3].getBytes("UTF-8");

String sigdata = new String(signature, "UTF-8");

0-???����T�?��K���( �?x�d??B�0�e98?}�υI`L�Q3E

あなたの例は文字化けした文字の混乱を表していますが(暗号化されていますか?)、強調表示したバイトは問題を示しています:

-115のバイト値から始めます。マイナスは、それが 0x7F を超えるバイト値であることを示します。その文字表現は、使用されるエンコーディングに大きく依存します。拡張 US-ASCII を想定すると、バイトは (この表によると) 文字ì(アクセント付き) を表します。これをデコードすると、(使用するエンコードによっては) デコーダーがバイト値 0x8D を理解できず、代わりに疑問符で表され?ます。疑問符は US-ASCII 文字63であり、それが 63 の由来であることに注意してください。

そのため、エンコーディングを一貫し使用し、システムのデフォルトに依存しないようにしてください。


また、文字列を表さないバイト配列 (ハッシュやその他の暗号化コンテンツなど) をデコードするために文字列エンコーディングを使用しないでください。

あなたのコメントによると、暗号化されたデータ (バイト) を読み取り、デコーダーを使用してそれらを文字列に変換しようとしていますか? それはあなたが期待するようには決して機能しません。何かを暗号化した後、そのまま保存する必要があるバイトの配列があります。それらを読み戻すときは、暗号化されていないバイトを取り戻すために、バイトを復号化器に通す必要があります。これらの復号化されたバイトが文字列を表す場合にのみ、エンコーディングを使用して文字列を復号化できます。

于 2013-03-19T13:46:31.247 に答える
0

これらのバイトを手動で文字列に変換することで、自分で余分な作業を行っています。これを目的としたクラスを使用してそれを行っていないのはなぜですか?

// get the file /logs/access.log
Path path = FileSystems.getRoot().getPath("logs", "access.log");
// open it, decoding UTF-8
BufferReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
// read a line of text, properly decoded
String line = reader.readLine();

または、Java 6 を使用している場合:

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("/logs/access.log"), "UTF-8"));
String line = reader.readLine();

リンク:

于 2013-03-19T13:40:18.280 に答える
0

私にはエンコードの問題のように聞こえます。

まず、ファイルが使用しているエンコーディングを知り、ファイルを読み取るときにそれを使用する必要があります。

次に、署名はバイト配列ですが、Java 文字列は常に Unicode です。別のエンコーディングが必要な場合 (ASCII が必要だと思います) getBytes("US-ASCII")、.

もちろん、入力が ascii の場合、これがエンコーディングの問題を引き起こす可能性があるのは奇妙です。

于 2013-03-19T13:44:16.953 に答える