java String.getBytes输出是怎么算出来的

以下代码为例:

System.out.println(Arrays.toString("中".getBytes("UTF-8")));

输出结果:

[-28, -72, -83]

Unicode编码是指定一个值对应一个字符
所以:0x4e2d --> 中,所以底层存储还是2个字节,只是在getBytes方法在得到时,底层进行了转换
将底层数据转换为UTF-8格式的规则:
在这里插入图片描述0x4e2d 范围在0x800 ~ 0xFFFF之间
0x4e2d二进制为:0100 1110 0010 1101
则UTF-8编码方式转换: 变为了三个字节,如下图
11100100 10111000 10101101
在这里插入图片描述三字节转为byte依次为
11100100 -> 有符号,减1 -> 11100011,取反 -> 00011100 -> 转10进制,4+8+16=28 -> -28
10111000 -> -72
10101101 -> -83

import cn.zhangsan.tools.enums.Algorithm;import com.google.common.collect.Maps;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.util.encoders.Hex;import java.net.MalformedURLException;import java.net.URL;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Security;import java.util.Base64;import java.util.Map;/** * @ClassName HashGeneratorUtils * @Description TODO * @Author ZhangSan_Plus * @Date 2024/7/29 20:04 * @Version 1.0 **/public class HashGeneratorUtils { static Map<Object, String> map = Maps.newLinkedHashMap(); static { Security.addProvider(new BouncyCastleProvider()); } public static void main(String[] args) { String input = "张三"; try { Map<Object, String> hashText = getHashText(input, 4); hashText.forEach((k, v) -> System.out.println(k + ":" + v)); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } public static String extractDomain(String urlString) { try { URL url = new URL(urlString); return url.getHost(); } catch (MalformedURLException e) { e.printStackTrace(); return null; } } private static Map<Object, String> getHashText(String text, int digest) throws NoSuchAlgorithmException { map.put(Algorithm.MD5, encryption(md5(text), digest)); map.put(Algorithm.SHA1, encryption(sha1(text), digest)); map.put(Algorithm.SHA256, encryption(sha224(text), digest)); map.put(Algorithm.SHA224, encryption(sha256(text), digest)); map.put(Algorithm.SHA512, encryption(sha384(text), digest)); map.put(Algorithm.SHA384, encryption(sha512(text), digest)); map.put(Algorithm.SHA3, encryption(sha3_256(text), digest)); map.put(Algorithm.RIPEMD160, encryption(ripemd160(text), digest)); return map; } private static byte[] md5(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("MD5"); return digest.digest(input.getBytes()); } private static byte[] sha1(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-1"); return digest.digest(input.getBytes()); } private static byte[] sha224(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-224"); return digest.digest(input.getBytes()); } private static byte[] sha256(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); return digest.digest(input.getBytes()); } private static byte[] sha384(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-384"); return digest.digest(input.getBytes()); } private static byte[] sha512(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-512"); return digest.digest(input.getBytes()); } private static byte[] sha3_256(String input) throws NoSuchAlgorithmException { MessageDigest digest = null; try { digest = MessageDigest.getInstance("SHA3-256", "BC"); } catch (NoSuchProviderException e) { throw new RuntimeException(e); } return digest.digest(input.getBytes()); } private static byte[] ripemd160(String input) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("RIPEMD160"); return digest.digest(input.getBytes()); } private static String toHexString(byte[] bytes) { return Hex.toHexString(bytes); } private static String toBase64(byte[] bytes) { return Base64.getEncoder().encodeToString(bytes); } private static String toBase64Url(byte[] bytes) { return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes); } private static String toBinary(byte[] bytes) { StringBuilder binaryString = new StringBuilder(); for (byte b : bytes) { for (int i = 7; i >= 0; i--) { binaryString.append(((b >> i) & 1) == 1 ? '1' : '0'); } binaryString.append(""); } return binaryString.toString().trim(); } private static String encryption(byte[] bytes, int encoding) { switch (encoding) { case 1: return toHexString(bytes); case 2: return toBinary(bytes); case 3: return toBase64(bytes); case 4: return toBase64Url(bytes); default: return ""; } }}
最新发布
03-31
### Java 实现多种哈希法及编码方式 #### 1. 使用 `MessageDigest` 类生成哈希值 Java 提供了标准库类 `java.security.MessageDigest` 来计哈希值。以下是针对 MD5、SHA-1 和 SHA-256 的实现。 ```java import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.Base64; public class HashExample { public static String getHash(String input, String algorithm) throws Exception { MessageDigest digest = MessageDigest.getInstance(algorithm); byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8)); return bytesToHex(hashBytes); } private static String bytesToHex(byte[] bytes) { StringBuilder result = new StringBuilder(); for (byte b : bytes) { result.append(String.format("%02x", b)); } return result.toString(); } public static void main(String[] args) throws Exception { String text = "HelloWorld"; // 计 MD5 哈希值 System.out.println("MD5: " + getHash(text, "MD5")); // 计 SHA-1 哈希值 System.out.println("SHA-1: " + getHash(text, "SHA-1")); // 计 SHA-256 哈希值 System.out.println("SHA-256: " + getHash(text, "SHA-256")); } } ``` 上述代码通过调用 `MessageDigest.getInstance()` 方法指定了具体的哈希法[^1],并将其应用于输入字符串上。最终返回的结果是以十六进制格式表示的哈希值。 --- #### 2. 将哈希值转换为其他编码方式 ##### a. 转换为 Base64 编码 可以利用 `java.util.Base64` 工具类将字节数组转换为 Base64 字符串: ```java public static String toBase64(byte[] bytes) { return Base64.getEncoder().encodeToString(bytes); } // 示例:在主函数中添加如下代码 System.out.println("MD5 Base64: " + toBase64(digest.digest())); ``` 此处展示了如何将原始字节数据转化为 Base64 表示形式[^5]。 ##### b. 转换为二进制字符串 可以通过逐位解析的方式将字节数组转为二进制字符串: ```java private static String bytesToBinary(byte[] bytes) { StringBuilder binaryString = new StringBuilder(); for (byte b : bytes) { binaryString.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0')); } return binaryString.toString(); } // 示例:在主函数中添加如下代码 System.out.println("MD5 Binary: " + bytesToBinary(md5.digest())); ``` 此部分实现了从字节数组到纯二进制字符串的映射过程。 --- #### 3. 图片文件的哈希处理 对于图片或其他类型的文件,可以直接读取其字节流并传递给 `MessageDigest` 进行处理。以下是一个基于图片路径生成 MD5 值的例子: ```java import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class ImageHashExample { public static void main(String[] args) throws IOException, Exception { byte[] imageBytes = Files.readAllBytes(Paths.get("path/to/image.jpg")); MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] hashBytes = md5.digest(imageBytes); System.out.println("Image MD5 Hex: " + bytesToHex(hashBytes)); // 十六进制输出 System.out.println("Image MD5 Base64: " + Base64.getEncoder().encodeToString(hashBytes)); // Base64 输出 } } ``` 该片段说明了如何加载外部资源(如图像)并通过指定法对其进行摘要运[^2]。 --- ### 总结 以上介绍了如何使用 Java 标准库完成多样的哈希法与编码操作。无论是简单的文本还是复杂的多媒体文件,都可以借助内置工具轻松达成目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值