基于 java.security.MessageDigest 和 AWT 的 文件 MD5 SHA 文件Hash校验程序

本文介绍了230527版本的程序,它改进了文件校验,支持大于4GB的文件,使用MessageDigest API按块处理,实现了MD5、SHA-256和SHA-512的校验,适合大型文件的高效验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于MessageDigest 和AWT的文件校验程序

介绍

可校验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);
		}
		
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kfepiza

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值