2016-01-31

Java でメッセージダイジェストを生成

Java の MessageDigest クラスは、MD5 あるいは SHA などのメッセージダイジェストアルゴリズムの機能を提供しています。

以前、bitWalk's: MD5 & SHA Checksum Utility で Windows 上で動作する MD5 & SHA Checksum Utility を紹介しましたが、Java で同じようなことを実現してみようと思い、簡単なサンプルを JavaFX で作ってみました。なお、MessageDigest クラスの使い方は、参考サイト [1] を参考にさせていただきました。

動作を確認した環境は次の通りです。

  • OS: Fedora 23 (x86_64)
  • Java: Java SE 1.8.0_72 (jdk1.8.0_72-1.8.0_72-fcs.x86_64)
  • IDE: NetBeans IDE 8.1

サンプルプログラムを以下に示しました。参考サイト [2] の GitHub にイメージを含む全ソースをアップしてあります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package hashcalc;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.xml.bind.DatatypeConverter;
 
public class HashCalc extends Application {
 
    String baseDir = getClass().getResource("image/").toString();
    Image icoApp = new Image(baseDir + "Binary.png");
    Image icoFile = new Image(baseDir + "File.png");
    Image icoPen = new Image(baseDir + "Pencil.png");
 
    File file;
    TextField field_sha256;
 
    @Override
    public void start(Stage primaryStage) {
 
        BorderPane root = new BorderPane();
        Scene scene = new Scene(root);
 
        GridPane gridpane = new GridPane();
        gridpane.setPadding(new Insets(5));
        gridpane.setHgap(5);
        gridpane.setVgap(2);
 
        ColumnConstraints column1 = new ColumnConstraints();
        ColumnConstraints column2 = new ColumnConstraints(600);
        ColumnConstraints column3 = new ColumnConstraints();
        gridpane.getColumnConstraints().addAll(column1, column2, column3);
 
        RowConstraints row1 = new RowConstraints();
        row1.setFillHeight(true);
        RowConstraints row2 = new RowConstraints();
        row2.setFillHeight(true);
        gridpane.getRowConstraints().addAll(row1, row2);
 
        // File Name label
        Label label_file = new Label("File Name");
        GridPane.setHalignment(label_file, HPos.RIGHT);
        gridpane.add(label_file, 0, 0);
 
        // File Name field
        TextField field_file = new TextField();
        field_file.setEditable(false);
        GridPane.setHalignment(field_file, HPos.LEFT);
        gridpane.add(field_file, 1, 0);
 
        // File Name button
        Button button_file = new Button();
        button_file.setGraphic(new ImageView(icoFile));
        button_file.setOnAction((ActionEvent t) -> {
            FileChooser fileChooser = new FileChooser();
            file = fileChooser.showOpenDialog(primaryStage);
            field_file.setText(file.toString());
            clearMessageDigest();
        });
        gridpane.add(button_file, 2, 0);
 
        // SHA-256 label
        Label label_sha256 = new Label("SHA-256");
        GridPane.setHalignment(label_sha256, HPos.RIGHT);
        gridpane.add(label_sha256, 0, 1);
 
        // SHA-256 field
        field_sha256 = new TextField();
        field_sha256.setEditable(false);
        GridPane.setHalignment(field_sha256, HPos.LEFT);
        gridpane.add(field_sha256, 1, 1);
 
        // SHA-256 button
        Button button_sha256 = new Button();
        button_sha256.setGraphic(new ImageView(icoPen));
        button_sha256.setOnAction((ActionEvent t) -> {
            try {
                String md = calcMessageDigest("SHA-256");
                field_sha256.setText(md);
            } catch (NoSuchAlgorithmException | IOException ex) {
                Logger.getLogger(HashCalc.class.getName()).log(Level.SEVERE, null, ex);
            }
        });
        gridpane.add(button_sha256, 2, 1);
 
        root.setCenter(gridpane);
        primaryStage.setResizable(false);
        primaryStage.setTitle("HashCalc");
        primaryStage.getIcons().add(icoApp);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
 
    void clearMessageDigest() {
        field_sha256.setText("");
    }
 
    String calcMessageDigest(String algorithm) throws NoSuchAlgorithmException, FileNotFoundException, IOException {
 
        if (isEmpty(file)) {
            return "";
        }
        if (!checkBeforeReadfile(file)) {
            return "";
        }
 
        MessageDigest md = MessageDigest.getInstance(algorithm);
        FileInputStream in = new FileInputStream(file);
 
        byte[] dataBytes = new byte[1024];
 
        int nread = 0;
        while ((nread = in.read(dataBytes)) != -1) {
            md.update(dataBytes, 0, nread);
        }
        byte[] mdbytes = md.digest();
 
        return DatatypeConverter.printHexBinary(mdbytes);
    }
 
    boolean isEmpty(File value) {
        return value == null || value.length() == 0;
    }
 
    static boolean checkBeforeReadfile(File read) {
        if (read.exists()) {
            if (read.isFile() && read.canRead()) {
                return true;
            }
        }
 
        return false;
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

実行例

試しに、Fedora 23 の Live-CD のイメージを使ってみましたが、まあ許容できる時間で結果を返してくれます。本格的なユーティリティプログラムとして使うには、もう少し GUI を作りこむ必要がありそうです。

参考サイト

  1. Java SHA Hashing Example
  2. bitwalk123/HashCalc

 

0 件のコメント: