システム開発ブログ

【Java】チェックサムファイルを生成する(SHA-256)

山岡

山岡 (2011年10月21日 10:00)
産業システム部 / システム開発事業部 / JAVA

インターネット経由でファイルをダウンロードしたときに、
チェックサムファイルを用いて、ファイルの破損チェック、改竄チェックを行うことがあります。

今回はJavaでチェックサムファイルを生成するコードを紹介します。
ロジックの細かい説明はしませんが、難しいことは書いてないので
1行ずつ読み進めていけば理解できると思います。

// 使い方:チェックサムファイル作成
//  1. download.csvからメッセージダイジェストを
//     生成する(SHA-256のアルゴリズム)
//  2. 生成したメッセージダイジェストを
//     download.sumとしてファイルに書きこむ

File csvFile = new File("C:\\test\\download.csv");
File sumFile = new File("C:\\test\\download.sum");
ChecksumUtil.createChecksumFile(csvFile, sumFile);


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.MessageDigest;


public class ChecksumUtil {

    /** Algorithm */
    private static final String ALGORITHM = "SHA-256";

    /**
     * チェックサムファイルを生成します。
     * @param src 生成元のファイル
     * @param sum 生成するチェックサムファイル
     */
    public static void createChecksumFile(File src, File sum)
    throws IOException, Exception {

        String sRecord = printDigest(getFileDigest(src));

        PrintStream ps = null;
        try {
            // Streamを作成します。
            ps = new PrintStream(
                          new FileOutputStream(sum)
                        , false
                        , "windows-31j"
                        );
            ps.println(sRecord);
        } catch (IOException e) {
            throw e;
        } finally {
            if (ps != null) {
                try {ps.flush();} catch (Exception e) {}
                try {ps.close();} catch (Exception e) {}
            }
        }
    }

    /**
     * ファイルからダイジェストを生成します。
     * @param path ダイジェストを生成するファイル
     * @return ダイジェスト(16進数)
     */
    public static byte[] getFileDigest(File path)
    throws Exception {

        // ファイルの中身からダイジェストを生成する
        MessageDigest md =
            MessageDigest.getInstance(ALGORITHM);

        FileInputStream in = null;
        try {
            in = new FileInputStream(path);

            // dat配列の先頭からlenまでのダイジェストを計算する
            byte[] dat = new byte[256];
            int len;
            while ((len = in.read(dat)) >= 0) {
                md.update(dat, 0, len);
            }
        } finally {
            if (in != null) {
                try{in.close();} catch (Exception e){}
            }
        }
        return md.digest();
    }

    /**
     * ダイジェスト(16進数)からダイジェスト(文字列)を生成します。
     * @param digest ダイジェスト(16進数)
     * @return ダイジェスト(文字列)
     */
    public static String printDigest(byte[] digest) {
        String sSum = "";
        for (int i = 0; i < digest.length; i++) {

            // byte型では128~255が負値になっているので補正
            int d = digest[i];
            if (d < 0) {
                d += 256;
            }

            // 0~15は16進数で1桁のため、2桁になるよう頭に0を追加
            if (d < 16) {
                sSum += "0";
            }
            sSum += Integer.toString(d, 16);
        }

        return sSum;
    }

}

システムのトラブル解決を承ります。すぐにシステムリフォームを体験できますシステム診断・システムリフォームのお申し込みはこちらから。

システム開発ブログ

Twitterでilovex_officialをフォローしてください

最近の記事

カテゴリー

部署

月別アーカイブ

以前の部署別ブログ

ページのトップ