介绍
可校验MD5 , SHA256 , SHA512等 , 基于MessageDigest 版本
代码
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.util.*;
//import javax.swing.JButton;
public class SHA_MD_MessageDigest extends Frame{
/**
*
*/
private static final long serialVersionUID = 5242216018207119189L;
static void pln(Object o) {System.out.println(o);}
public final SHA_MD_MessageDigest I;
public final TextArea resultShow = new TextArea("这里展示结果");
public final HashMap<String, MessageDigest> DigestGroup = new HashMap<>();
public final LinkedHashMap<String, Panel> ButtonForComputedGroup = new LinkedHashMap<>();
{
Set<String> set = java.security.Security.getAlgorithms("MessageDigest"); //获得支持的格式
ArrayList<String> nmAl = new ArrayList<>(set);
// nmAl.sort(new Comparator<String>() {
// @Override
// public int compare(String o1, String o2) {
// int rlt = o1.compareTo(o2);
// return rlt;
// }
// });
nmAl.sort((o1,o2)->o1.compareTo(o2));
try {
for(String nm : set) {
DigestGroup.put(nm, MessageDigest.getInstance(nm));
}
nmAl.forEach(nm->{
ButtonForComputedGroup.put(nm, new Btn(nm));
});
}catch(Exception ex) {ex.printStackTrace();}
}
//constructor 构造方法在此
public SHA_MD_MessageDigest() {
I=this;
setTitle("文件校验, 点击按钮选择文件, 文件必须<2G 32位Integer");
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
I.dispose();
System.exit(0);
}
});
setLayout(new GridLayout(2, 0, 1, 3));
Panel up = new Panel(); add(up); up.setBackground(Color.DARK_GRAY);
Panel down = new Panel(); add(down);
ButtonForComputedGroup.forEach((lb,btn)->{
up.add(btn);
});
down.setLayout(new BorderLayout(200,200)); down.add(resultShow);
setBounds(160, 200, 1600, 365);
setVisible(true);
// show();
}
public static void main(String ags[]) {new SHA_MD_MessageDigest();}
void computed(String nm) {
pln(nm);
String map = "0123456789abcdef";
FileDialog fileDialog = new FileDialog(this, "选择要生成Hash的文件", FileDialog.LOAD);
fileDialog.setVisible(true);
String directoryStr = fileDialog.getDirectory() , fileStr = fileDialog.getFile();
if(directoryStr!=null && fileStr!=null) {
try {
String pathStr = directoryStr+fileStr;
resultShow.setText("正在计算 "+pathStr+" 的"+nm+"值");
FileInputStream is = new FileInputStream(pathStr);
byte bf[] = new byte[is.available()];
is.read(bf); is.close();
MessageDigest digest = DigestGroup.get(nm);
bf = digest.digest(bf);
StringBuilder sb = new StringBuilder(bf.length*2);
for(byte b : bf) {
int idx1=(b&0xff)>>>4 , idx2=b<<28>>>28;
pln("idx1="+idx1+" idx2="+idx2);
sb.append(map.charAt(idx1)).append(map.charAt(idx2));
}
String hex = sb.toString();
resultShow.setText(hex);
}catch(Throwable ex) {ex.printStackTrace(); resultShow.setText(ex.toString()); }
}
}
class Btn extends Panel{
/**
* 镶嵌在Panel中的Button
*/
private static final long serialVersionUID = -3494086542207800072L;
public final Button btn;
Btn(String label){
super();
this.setBackground(Color.blue);
// setLayout(new BorderLayout());
setLayout(null);
setSize(210,60);
btn = new Button(label);
switch (label) {
case"MD5","SHA-256": btn.setForeground(Color.BLUE); break;
case"SHA-512": btn.setForeground(Color.WHITE);btn.setBackground(new Color(0,168,255)); break;
}
btn.setBounds(5, 5, 200, 50);
setFont(new Font("宋体", Font.CENTER_BASELINE, 25));
btn.addActionListener(ev->{
computed(btn.getActionCommand());
});
add(btn);
}
}
}
230527版
不再将大文件读入一个数组, 可支持大于4G的文件. 在jdk17下测试通过.
原理是先用messageDigest的update(byte[] input, int offset, int len)
方法用缓存数组分段读取文件内容, 在调用不带参数的digest()
方法获得校验码字节数组
package za;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.util.*;
//import javax.swing.JButton;
public class SHA_MD_MessageDigest_230527 extends Frame{
/**
*
*/
private static final long serialVersionUID = 5242216018207119189L;
static void pln(Object o) {System.out.println(o);}
public final SHA_MD_MessageDigest_230527 I;
public final TextArea resultShow = new TextArea("这里展示结果");
public final HashMap<String, MessageDigest> DigestGroup = new HashMap<>();
public final LinkedHashMap<String, Panel> ButtonForComputedGroup = new LinkedHashMap<>();
{
Set<String> set = java.security.Security.getAlgorithms("MessageDigest"); //获得支持的格式
ArrayList<String> nmAl = new ArrayList<>(set);
// nmAl.sort(new Comparator<String>() {
// @Override
// public int compare(String o1, String o2) {
// int rlt = o1.compareTo(o2);
// return rlt;
// }
// });
nmAl.sort((o1,o2)->o1.compareTo(o2));
try {
for(String nm : set) {
DigestGroup.put(nm, MessageDigest.getInstance(nm));
}
nmAl.forEach(nm->{
ButtonForComputedGroup.put(nm, new Btn(nm));
});
}catch(Exception ex) {ex.printStackTrace();}
}
//constructor 构造方法在此
public SHA_MD_MessageDigest_230527() {
I=this;
setTitle("文件校验, 点击按钮选择文件, 文件必须<2G 32位Integer");
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
I.dispose();
System.exit(0);
}
});
setLayout(new GridLayout(2, 0, 1, 3));
Panel up = new Panel(); add(up); up.setBackground(Color.DARK_GRAY);
Panel down = new Panel(); add(down);
ButtonForComputedGroup.forEach((lb,btn)->{
up.add(btn);
});
down.setLayout(new BorderLayout(200,200)); down.add(resultShow);
setBounds(160, 200, 1600, 365);
setVisible(true);
// show();
}
public static void main(String ags[]) {new SHA_MD_MessageDigest_230527();}
void computed(String nm) {
pln(nm);
String map = "0123456789abcdef";
FileDialog fileDialog = new FileDialog(this, "选择要生成Hash的文件", FileDialog.LOAD);
fileDialog.setVisible(true);
String directoryStr = fileDialog.getDirectory() , fileStr = fileDialog.getFile();
if(directoryStr!=null && fileStr!=null) {
try {
String pathStr = directoryStr+fileStr;
resultShow.setText("正在计算 "+pathStr+" 的"+nm+"值");
FileInputStream is = new FileInputStream(pathStr);
MessageDigest digest = DigestGroup.get(nm);
byte[] bf = new byte[10240];
int numRead;
do {
numRead = is.read(bf);
if (numRead > 0) {
digest.update(bf, 0, numRead);
}
} while (numRead != -1);
is.close();
bf = digest.digest();
StringBuilder sb = new StringBuilder(bf.length*2);
for(byte b : bf) {
int idx1=(b&0xff)>>>4 , idx2=b<<28>>>28;
pln("idx1="+idx1+" idx2="+idx2);
sb.append(map.charAt(idx1)).append(map.charAt(idx2));
}
String hex = sb.toString();
resultShow.setText(hex);
}catch(Throwable ex) {ex.printStackTrace(); resultShow.setText(ex.toString()); }
}
}
class Btn extends Panel{
/**
* 镶嵌在Panel中的Button
*/
private static final long serialVersionUID = -3494086542207800072L;
public final Button btn;
Btn(String label){
super();
this.setBackground(Color.blue);
// setLayout(new BorderLayout());
setLayout(null);
setSize(210,60);
btn = new Button(label);
switch (label) {
case"MD5","SHA-256": btn.setForeground(Color.BLUE); break;
case"SHA-512": btn.setForeground(Color.WHITE);btn.setBackground(new Color(0,168,255)); break;
}
btn.setBounds(5, 5, 200, 50);
setFont(new Font("宋体", Font.CENTER_BASELINE, 25));
btn.addActionListener(ev->{
computed(btn.getActionCommand());
});
add(btn);
}
}
}