ファイルのコンテンツの Java で SHA-1 を生成してから読み込もうとしています。16 進数が 1 つ変更されますが、その理由がわかりません。
コード:ファイルへの書き込み
//writer:
import java.util.*;
import java.io.*;
import java.security.*;
public class Writer{
public static void main(String []args)throws Exception{
InputStream is = new FileInputStream("input.txt");
PrintStream os=new PrintStream(new File("out.txt"));
byte[] buffer = new byte[1024];
String str;
MessageDigest complete = MessageDigest.getInstance("SHA-1");
MessageDigest partial = MessageDigest.getInstance("SHA-1");
int numRead;
do {
numRead = is.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
partial.update(buffer,0,numRead);
byte []digest=partial.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(String.format("%x", digest[i]));
}
System.out.println(sb.toString());
str=new String(digest);
os.println(str);
partial.reset();
}
} while (numRead != -1);
byte []digest=complete.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(String.format("%x", digest[i]));
}
System.out.println(sb.toString());
str=new String(digest);
os.println(str);
is.close();
os.close();
}
}
ファイルを読み取るコード
//Reader:
import java.util.*;
import java.io.*;
import java.security.*;
public class Reader{
public static void main(String []args)throws Exception{
BufferedReader is = new BufferedReader(new FileReader("out.txt"));
String str;
while((str=is.readLine())!=null)
{
//System.out.println(str);
byte []digest=str.getBytes();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(String.format("%x", digest[i]));
}
System.out.println(sb.toString());
}
is.close();
}
}
別のコードを input.txt として使用しました。5 つの出力行を生成します。最初の 4 行の読み取りと変換は問題ありません。最後の行には、16 進数の inputfile:input.txt が変更されています。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author biborno
*/
import java.io.*;
import java.security.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
public class Torrent {
private static void encodeObject(Object o, OutputStream out) throws IOException {
if (o instanceof String)
encodeString((String)o, out);
else if (o instanceof Map)
encodeMap((Map)o, out);
else if (o instanceof byte[])
encodeBytes((byte[])o, out);
else if (o instanceof Number)
encodeLong(((Number) o).longValue(), out);
else
throw new Error("Unencodable type");
}
private static void encodeLong(long value, OutputStream out) throws IOException {
out.write('i');
out.write(Long.toString(value).getBytes("US-ASCII"));
out.write('e');
}
private static void encodeBytes(byte[] bytes, OutputStream out) throws IOException {
out.write(Integer.toString(bytes.length).getBytes("US-ASCII"));
out.write(':');
out.write(bytes);
}
private static void encodeString(String str, OutputStream out) throws IOException {
encodeBytes(str.getBytes("UTF-8"), out);
}
private static void encodeMap(Map<String,Object> map, OutputStream out) throws IOException{
// Sort the map. A generic encoder should sort by key bytes
SortedMap<String,Object> sortedMap = new TreeMap<String, Object>(map);
out.write('d');
for(Entry<String, Object> e : sortedMap.entrySet()) {
encodeString(e.getKey(), out);
encodeObject(e.getValue(), out);
}
out.write('e');
}
private static byte[] hashPieces(File file, int pieceLength) throws IOException {
MessageDigest sha1;
try {
sha1 = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
throw new Error("SHA1 not supported");
}
InputStream in = new FileInputStream(file);
ByteArrayOutputStream pieces = new ByteArrayOutputStream();
byte[] bytes = new byte[pieceLength];
int pieceByteCount = 0, readCount = in.read(bytes, 0, pieceLength);
while (readCount != -1) {
pieceByteCount += readCount;
sha1.update(bytes, 0, readCount);
if (pieceByteCount == pieceLength) {
pieceByteCount = 0;
pieces.write(sha1.digest());
}
readCount = in.read(bytes, 0, pieceLength-pieceByteCount);
}
in.close();
if (pieceByteCount > 0)
pieces.write(sha1.digest());
return pieces.toByteArray();
}
public static void createTorrent(File file, File sharedFile, String announceURL) throws IOException {
final int pieceLength = 512*1024;
Map<String,Object> info = new HashMap<String,Object>();
info.put("name", sharedFile.getName());
info.put("length", sharedFile.length());
info.put("piece length", pieceLength);
info.put("pieces", hashPieces(sharedFile, pieceLength));
Map<String,Object> metainfo = new HashMap<String,Object>();
metainfo.put("announce", announceURL);
metainfo.put("info", info);
OutputStream out = new FileOutputStream(file);
encodeMap(metainfo, out);
out.close();
}
public static void main(String[] args) throws Exception {
createTorrent(new File("C:\\Documents and Settings\\biborno\\Desktop\\Test.text.torrent"), new File("C:\\Documents and Settings\\biborno\\Desktop\\Test.text"), "http://example.com/announce");
}
}
ライターの出力:
f1556b25a651c3dc4831871ab3fce2d239c7f0d4
4ed5c741dbf78059fef3733340efcf9b16b4594f
e2b66127e6f25648e9e2d21cb18e26d4a541a17
26c213a35b3f2ccae28ad5e3b98b5a02386c368
e7d152cd8f5f22949abbc11eb049451c511df07b
out.txt:
ñUk%¦QÃÜH1‡³üâÒ9ÇðÔ
NÕÇAÛ÷€Yþós3@ïÏ›´YO
â¶a'æòVHéâÒ±Ž&Ô¥
&£[òÌ®(^;˜µ #†Ãh
çÑRÍ?_"”š»Á°IEQð{
読者のアウトプット
f1556b25a651c3dc4831871ab3fce2d239c7f0d4
4ed5c741dbf78059fef3733340efcf9b16b4594f
e2b66127e6f25648e9e2d21cb18e26d4a541a17
26c213a35b3f2ccae28ad5e3b98b5a02386c368
e7d152cd3f5f22949abbc11eb049451c511df07b