字母a的编码是十六进制的0x41,字母b是0x42,以此类推;ascii只能用于英文编码,最多只能有127个字符。要想对更多的文字进行编码,就需要用占用两个字节的unicode.而中文的“中”字使用unicode编码就是0x4e2d,使用utf-8则需要3个字节编码。
所以,最简单的编码是直接给每个字符指定一个若干字节表示的整数,复杂一点的编码就需要根据已有的编码推算出来。比如utf-8编码,它是一种不定长编码,但可以从给定字符的unicode编码推算出来。
1、url编码1.1概念
url编码是浏览器发送给服务器时使用的编码,它通常附加在url的参数部分,eg
https://www.baidu.com/s?wd=%e6%9d%a8%e9%a2%96
之所以需要url编码,是因为处于兼容性考虑,很多服务器只识别ascii字符。但如果url中包含中文,日文这些非ascii字符怎么办?url编码有一套规则:
·如果字符是a~z,a~z, 0~9以及-,_,.,*,则保持不变;
·如果是其他字符,先转换为utf-8编码,然后对每个字节以%xx表示。
例如:字符中的utf-8编码是0xe4b8ad,因此,它的url编码是%e4%b8%ad。url编码总是大写。
1.2代码示例(编码和解码)
对url中的中文进行编码
package com.yy.demo01; import java.io.unsupportedencodingexception;import java.net.urldecoder;import java.net.urlencoder; public class test01 { public static void main(string[] args) throws unsupportedencodingexception { string url = "http://www.baidu.com/s?wd="; string value = "杨颖"; //对url中的中文进行编码 string result = urlencoder.encode(value, "utf-8"); system.out.println("url参数:" + result); system.out.println("完整网址:" + (url+result)); } }
对url中的中文进行解码
package com.yy.demo01; import java.io.unsupportedencodingexception;import java.net.urldecoder;import java.net.urlencoder; public class test01 { public static void main(string[] args) throws unsupportedencodingexception { //对url中的中文进行解码 string param = "https://www.baidu.com/s?wd= %e6%88%91%e6%9c%ac%e5%b0%86%e5%bf%83%e5%90%91%e6%98%8e%e6%9c%88\r\n"; string conent = urldecoder.decode(param, "utf-8"); system.out.println(conent); } }
注意:url编码是编码算法,不是加密算法。
url编码目的:把任意文本数据编码为%前缀表示的文本,编码后的文本仅包含a-z,a-z,0-9,-,_,.,*和%,便于浏览器和服务器处理。
2、base64编码2.1基本概念
url 编码是对字符进行编码,表示成%xx的形式,而base64编码是对二进制数据进行编码,表示成文本格式。
base64编码可以把任意长度的二进制数据变为纯文本,并且纯文本内容中且只包含指定字符内容:a~2 .a~z、0~9、+、7、日。它的原理是把3字节的二进制数据按6bit一组,用4个int整数表示,然后查表,把int整数用索引对应到字符,得到的字符串。
6位整数的范围总是e ~63,所以,能用64个字符表示:字符a~z 对应索引e~ 25,字符a~z对应索引26~5
2.2在java中,二进制数据就是byte[ ] 数组、java标准库提供base64来对byte[ ]数组进行编码
编码代码示例:使用base64.getencoder().encodetostring("xxxx".getbytes())方法进行编码(它返回值为一个字节数组,所以编码内容要转换为字节!)。
package com.yy.demo01; import java.io.unsupportedencodingexception;import java.nio.charset.standardcharsets;import java.util.base64; public class test02 { public static void main(string[] args) throws unsupportedencodingexception { string content = "红尘客栈风似刀,骤雨落宿命敲"; string result = base64.getencoder().encodetostring(content.getbytes()); system.out.println(result); } }
解码内容
使用base64.getdecoder().decode(str)方法进行解码
package com.yy.demo01; import java.io.unsupportedencodingexception;import java.nio.charset.standardcharsets;import java.util.base64; public class test02 { public static void main(string[] args) throws unsupportedencodingexception { string str = "57qi5bcy5a6i5qci6aoo5ly85yia77ym6aqk6zuo6jc95a6/5zg95pwy"; byte[] bytearray = base64.getdecoder().decode(str); string line = new string(bytearray,"utf-8"); system.out.printf("解码后:" +line); } }
2.3、用base64进行图片的编码和解码
先使用files.readallbytes(paths.get("图片的本地路径"))读取图片的字节数组,然后使用base64.getencoder().encodetostring(读取到的图片的字节数组)来进行编码,转化成字符串类型。使用base64.getdecoder().decode(图片的字符串)解码,files.write()写入指定路径。
package com.yy.demo01; import java.io.ioexception;import java.nio.file.files;import java.nio.file.paths;import java.util.base64; public class test03 { public static void main(string[] args) throws ioexception { //读取图片(字节数组) byte[] imagebytearray = files.readallbytes(paths.get("c:\\users\\lenovo\\pictures\\saved pictures\\qq图片20220505163951.jpg")); //将字节数组进行base64编码,转换成“字符串形式” string imagedatastr = base64.getencoder().encodetostring(imagebytearray); system.out.println(imagedatastr); //base64解码 byte[] imageresultbytearray = base64.getdecoder().decode(imagedatastr); files.write(paths.get("d:\\1\\3\\难哄.jpg"), imageresultbytearray); } }
2.4、从文本文件中读取mp3文件
package com.yy.demo01; import java.io.ioexception;import java.nio.file.files;import java.nio.file.paths;import java.util.base64;import java.util.list; public class test05 { public static void main(string[] args) throws ioexception { //从文本文件中读取mp3文件 list<string> lines = files.readalllines(paths.get("c:\\users\\lenovo\\documents\\tencent files\\2452845234\\filerecv\\mojito.txt")); stringbuilder sb = new stringbuilder(); for(string ln : lines) { sb.append(ln); } //base解码 byte[] mp3arraybase = base64.getdecoder().decode(sb.tostring()); files.write(paths.get("d:\\1\\3\\mojito.mp3"), mp3arraybase); } }
二、常见的哈希算法总结哈希算法(hash)又称摘要算法(digest),它的作业是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的是;为了验证原始数据是否被篡改。
哈希算法最重要的特点就是:
.相同的输入一定得到相同的输出
.不同的输入大概率得到不同的输出
java字符串的hashcode()就是一个哈希算法输入是任意字符串,输出的是固定的4字节int整数;
"hello".hashcode(); // 0x5e918d2"hello, java".hashcode(); // 0x7a9d88e8"hello, bob".hashcode(); // 0xa0dbae2f
哈希碰撞
两个不同的输入得到了相同的输出:
"aaaaaa".hashcode(); // 0x7460e8c0"bbaabb".hashcode(); // 0x7460e8c0 "通话".hashcode(); // 0x11ff03"重地".hashcode(); // 0x11ff03
常用哈希算法:md
"md5"算法加密普通字符串
package com.yy.demo02; import java.security.messagedigest;import java.security.nosuchalgorithmexception; public class test02 { public static void main(string[] args) { string password = "hckzfsd1"; //7d18b6dc254c73427481f3083a3669 //7d18b6dc254c734274810f30083a3669 try { messagedigest digest = messagedigest.getinstance("md5"); digest.update(password.getbytes()); byte[] resultbytearray = digest.digest(); stringbuilder result = new stringbuilder(); for(byte bite:resultbytearray) { result.append(string.format("%02x", bite)); } system.out.println(result); system.out.println(result.length()); } catch (nosuchalgorithmexception e) { e.printstacktrace(); } } }
md5算法加密图片
package com.yy.demo02; import java.io.ioexception;import java.nio.file.files;import java.nio.file.paths;import java.security.messagedigest;import java.security.nosuchalgorithmexception;import java.util.arrays; public class test03 { public static void main(string[] args) { try { byte[] imagebytearray = files.readallbytes(paths.get("d:\\1\\3\\周杰伦.jpg")); messagedigest digest = messagedigest.getinstance("md5"); digest.update(imagebytearray); byte[] resultbytearray = digest.digest(); system.out.println(arrays.tostring(resultbytearray)); system.out.println(resultbytearray.length); stringbuilder digestresult = new stringbuilder(); for(byte b : resultbytearray) { digestresult.append(string.format("%02x", b)); } system.out.println(digestresult); } catch (nosuchalgorithmexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } } }
"sha-1"算法加密普通字符串
package com.yy.demo02; import java.security.messagedigest;import java.security.nosuchalgorithmexception;import java.util.arrays;import java.util.uuid; public class test04 { public static void main(string[] args) { string password = "wbjxxmy"; string salt = uuid.randomuuid().tostring().substring(0, 5); system.out.println(salt); try { messagedigest digest = messagedigest.getinstance("sha-1"); digest.update(password.getbytes()); digest.update(salt.getbytes()); byte[] resultbytearray = digest.digest(); system.out.println(arrays.tostring(resultbytearray)); system.out.println(resultbytearray.length); stringbuilder result = new stringbuilder(); for(byte b : resultbytearray) { result.append(string.format("%02x", b)); } system.out.println(result); } catch (nosuchalgorithmexception e) { e.printstacktrace(); } } }
"hmacmd5"加密普通字符串
package com.yy.demo02; import java.security.invalidkeyexception;import java.security.nosuchalgorithmexception;import java.util.arrays; import javax.crypto.keygenerator;import javax.crypto.mac;import javax.crypto.secretkey; public class test06 { public static void main(string[] args) { string password = "zylsmq"; try { //1.生成秘钥 //秘钥生成器keygenerator keygenerator keygen = keygenerator.getinstance("hmacmd5"); //生成秘钥 secretkey key = keygen.generatekey(); //获取秘钥key的字节数组(64) byte[] keybytearray = key.getencoded(); system.out.println("秘钥字节数组:" + arrays.tostring(keybytearray)); system.out.println("秘钥长度:" + keybytearray.length); stringbuilder keybyteresult = new stringbuilder(); for(byte b : keybytearray) { keybyteresult.append(string.format("%02x", b)); } system.out.println(keybyteresult); //2.加密 mac mac = mac.getinstance("hmacmd5"); mac.init(key); //更新原始内容 mac.update(password.getbytes()); //加密 byte[] resultbytearray = mac.dofinal(); system.out.println("加密结果:" + resultbytearray.length + "字节"); stringbuilder resultstr = new stringbuilder(); for(byte b : resultbytearray) { resultstr.append(string.format("%02x", b)); } system.out.println("加密结果:" + resultstr); system.out.println("加密结果长度" + resultstr.length()); } catch (nosuchalgorithmexception e) { e.printstacktrace(); } catch (invalidkeyexception e) { e.printstacktrace(); } } }
以上就是java加密与安全实例分析的详细内容。
