算法加密与解密、字符编码与字符集

news2024/11/17 16:05:11

加密算法

加密保证数据不会被窃取或者修改

可逆和不可逆加密

区分在于加密后的结果是否可以还原

可逆加密:安全传输数据时使用(如jwt中的数据)
    AES:流加密  DES:块加密
    RSA  HS256  


不可逆加密:同一个文件或内容每次加密的结果一样
    如:保存用户密码
    验证文件的完整性(安装客户端时 访问后端服务器该客户端唯一的MD5值 ,再到本地对客户端计算生成MD5值 如果一致 则认为客户端没有被修改 可以安装)
    网盘秒传(本地文件生成MD5值 网盘服务端缓存中查询MD5值是否存在,如果存在直接引用之前的文件 )


对称和非对称加密

都是可逆加密,区分点在于加密和解密使用的秘钥是否相同

对称:加密和解密秘钥相同
 

AES  DES  HS256

非对称:加密和解密秘钥不同  安全

RSA: 私钥(加密) 公钥(解密) ,可以理解为字符串

RSA算法是一种非对称的加密算法(即:加密、解密的密钥不同) ,通常是生成两把密钥,分别是私钥公钥,其中私钥保密,公钥对外公开。

RSA加解密过程:使用公钥将数据加密,并通过私钥对加密信息进行解密。针对我们遇到的问题,公钥放在前端对用户名密码进行加密,私钥放在服务端对前端提交的加密数据进行解密,然后在做登陆的业务操作


散列

散列算法

压缩映射:散列又称为哈希,是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。

哈希算法(Hash)又称摘要算法(Digest),哈希算法的目的就是为了验证原始数据是否被篡改。

主流的散列算法有MD5和SHA-1,其主要任务是验证数据的完整性

散列算法特色算法

  1. 固定大小:散列函数能够接收任意大小数据,并输出固定大小散列值,MD5获得的散列值大小是128bit,SHA-1获得的散列值大小是160bit
  2. 雪崩效应:原始数据只要修改,计算获得的散列值将会发生巨大变化
  3. 单向:只可能从原始数据计算获得散列值,不可能从散列值恢复数据
  4. 冲突避免:几乎不能找到另一个数据和当前数据计算的散列值相同,所以散列函数能确保数据的惟一性

一个字节是8位: 

二进制8位:xxxxxxxx ,范围:00000000-11111111,表示0到255。

一位16进制数(0-F),用二进制表示是xxxx,范围:0000 - 1111,表示:0到16

1个字节=2个16进制字符


MD5算法

Java 中,java.security.MessageDigest 中已经定义了 MD5 的计算,我们只需要简单地调用即可得到 MD5 的128 位整数,然后将此 128 位计 16 个字节转换成 16 进制表示即可。

public class Net {
    public static char hexDigits[]={'0','1','2','3','4','5','6','7','8','9',
            'A','B','C','D','E','F','G',
            'H','I','J','K','L','M','N',
            'O','P','Q','R','S','T',
            'U','V','W','X','Y','Z'};



    public static void main(String[] args) throws Exception {
        // 创建一个MessageDigest实例
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 反复调用update输入数据
        md.update("心有猛虎,细嗅蔷薇".getBytes("UTF-8"));
        //MD5 的计算结果是一个128位的长整数
        byte[] result = md.digest();

//16进制字符串形式密文(方式一)----------------------------------------------------------
        System.out.println(new BigInteger(1, result).toString(16));

//16进制字符串形式密文(方式二)----------------------------------------------------------
        //把密文转换成16进制字符串的形式
        int j = result.length;
        char str[] = new char[j * 2];
        int k = 0;
        for (int i = 0; i < j; i++) {
            byte byte0 = result[i];
            str[k++] = hexDigits[byte0 >>> 4 & 0xf];
            str[k++] = hexDigits[byte0 & 0xf];
        }
        System.out.println(str);

//16进制字符串形式密文(方式三)----------------------------------------------------------
        //这时需要一个StringBuffer来存储转译后的加密字符
        StringBuffer sb = new StringBuffer();
        //加密通常使用十六进制字符加密
        char[] chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
                'b', 'c', 'd', 'e', 'f', };
        //转换为16进制字符串
        for(byte b:result){
            sb.append(chars[(b >> 4) & 15]);
            sb.append(chars[b & 15]);
        }
        System.out.println(sb.toString());
    }
}

运行结果

彩虹表:一个预先计算好的常用口令和它们的MD5的对照表

采取措施来抵御彩虹表攻击,方法是对每个口令额外添加随机数,这个方法称之为加盐(salt):

加盐的目的在于使黑客的彩虹表失效,即使用户使用常用口令,也无法从MD5反推原始口令

 加盐Salt加密

在原始密码密文的基础之上,再加入一个随机字符串,从而达到让用户的密码更复杂的效果。这个随机字符串,便是盐。

//3、密码加密
//生成盐
String salt = UUID.randomUUID().toString().substring(0,8);
//MD5加密相同的字符串加密后的结果一样 ,所以md5会结合加盐保证安全
String endcodePwd = DigestUtils.md5Hex(DigestUtils.md5Hex(password)+salt);
userEntity.setSalt(salt);
userEntity.setPassword(endcodePwd);
//初始化用户的默认值
byte[] encode = Base64.getEncoder().encode(("谷粉" + UUID.randomUUID().toString().substring(0, 8)).getBytes());
userEntity.setNickname(new String(encode));
userEntity.setCreateTime(new Date());
userEntity.setIntegration(0);
userEntity.setGrowth(0);
userEntity.setLevelId(1L);
userEntity.setStatus(1);
//4、保存到数据库
this.save(userEntity);

注意:salt我们也存储了 


SHA-1算法

SHA算法实际上是一个系列,包括SHA-0(已废弃)、SHA-1、SHA-256、SHA-512等。在Java中使用SHA-1,和MD5完全一样,只需要把算法名称改为"SHA-1"

单向散列函数的安全性在于其产生散列值的操作过程具有较强的单向性。如果在输入序列中嵌入密码,那么任何人在不知道密码的情况下都不能产生正确的散列值,从而保证了其安全性

数字签名

通过散列算法可实现数字签名实现,数字签名的原理是将要传送的明文通过一种函数运算(Hash)转换成报文摘要(不同的明文对应不同的报文摘要),报文摘要加密后与明文一起传送给接受方,接受方将接受的明文产生新的报文摘要与发送方的发来报文摘要解密比较,比较结果一致表示明文未被改动,如果不一致表示明文已被篡改。

public class Net {
    public static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f'};


    public static void main(String[] args) throws Exception {
        // 创建一个MessageDigest实例
        MessageDigest md = MessageDigest.getInstance("SHA1");
        // 反复调用update输入数据
        md.update("helloworld".getBytes("UTF-8"));
        //MD5 的计算结果是一个128位的长整数
        byte[] result = md.digest();

//16进制字符串形式密文(方式一)----------------------------------------------------------
        //把密文转换成16进制字符串的形式
        int j = result.length;
        char str[] = new char[j * 2];
        int k = 0;
        for (int i = 0; i < j; i++) {
            byte byte0 = result[i];
            str[k++] = hexDigits[byte0 >>> 4 & 0xf];
            str[k++] = hexDigits[byte0 & 0xf];
        }
        System.out.println(str);

//16进制字符串形式密文(方式二)----------------------------------------------------------
        StringBuilder ret = new StringBuilder(result.length * 2);
        for (int i = 0; i < result.length; i++) {
            ret.append(hexDigits[(result[i] >> 4) & 0x0f]);
            ret.append(hexDigits[result[i] & 0x0f]);
        }
        System.out.println(ret.toString());

//16进制字符串形式密文(方式三)----------------------------------------------------------
        int i;
        StringBuffer buf = new StringBuffer("");
        for (int offset = 0; offset < result.length; offset++) {
            i = result[offset];
            if (i < 0)
                i += 256;
            if (i < 16)
                buf.append("0");
            buf.append(Integer.toHexString(i));
        }
        System.out.println(buf.toString());
    }
}

运行结果


字符集

编码、解码

计算机底层并没有文本文件、图片文件之分,它只是记录着每个文件的二进制序列。

字符集:包含着字符和二进制序列之间的对应关系,一个字符对应一个二进制序列。

乱码:编码、解码使用的字符集不一致导致

Windows中文本文件的默认字符集是GBK。

MySQL在8.0版本之前,默认字符集为latin1,8.0版本默认字符集为utf8mb4

ISO8859-1 字符集,也就是 Latin-1,是西欧常用字符,包括德法两国的字母。

ISO8859-2 字符集,也称为 Latin-2,收集了东欧字符。

ISO8859-3 字符集,也称为 Latin-3,收集了南欧字符。

字符集(Character Set):是指多个字符的集合。不同的字符集包含的字符个数不一样、包含的字符不一样、对字符的编码方式也不一样。如:


ASCII字符集

字符编码是指一种映射规则,根据这个规则来将字符映射到相应的码点(数值)上面

ASCII字符集

ASCII字符集只包含了128字符,这个字符集收录的主要字符是英文字母、阿拉伯字母和一些简单的控制字符

ASCII 编码方式是一种固定长度的编码方式,每个字符都使用 7 位二进制编码来表示。长度为1个字节, 有符号字符型数


ASCII码对照表

ASCII码中,

第0~32号及第127号是控制字符,常用的有LF(换行)、CR(回车);

第33~126号是字符,

其中第48~57号为0~9十个阿拉伯数字;

65~90号为26个大写英文字母,

97~122号为26个小写英文字母,

其余的是一些标点符号、运算符号等

ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUT32(space)64@96
1SOH33!65A97a
2STX34"66B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL
特殊字符解释
NUL空VT 垂直制表SYN 空转同步
STX 正文开始CR 回车CAN 作废
ETX 正文结束SO 移位输出EM 纸尽
EOY 传输结束SI 移位输入SUB 换置
ENQ 询问字符DLE 空格ESC 换码
ACK 承认DC1 设备控制1FS 文字分隔符
BEL 报警DC2 设备控制2GS 组分隔符
BS 退一格DC3 设备控制3RS 记录分隔符
HT 横向列表DC4 设备控制4US 单元分隔符
LF 换行NAK 否定DEL 删除

Unicode字符集

Unicode 标准始终使用十六进制数字标识唯一的码点(code point),码点用于表示该字符在字符集中的位置

Unicode字符集

Unicode字符集是一个很大的字符集合,包含了世界上几乎所有的字符,用于表示人类语言、符号和表情等各种信息

为了在计算机中存储和传输 Unicode 字符集中的字符,需要使用一种编码方式。
UTF-8 UTF-16 UTF-32 都是 Unicode 字符集的编码方式,用于将 Unicode 字符集中的字符转换成字节序列,以便于存储和传输。 它们的差别在于使用的 字节长度不同

UTF-8编码

UTF-8就是在互联网上使用最广的一种Unicode的实现方式。UTF-8编码是Unicode的实现方式之一。

UTF-8最大的一个特点,就是它是一种可变长度的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度

UTF-8 是一种可变长度的编码方式
  1. 对于 ASCII 字符(码点范围为 0x00~0x7F ),使用一个字节表示
  2. 对于其他 Unicode 字符,使用两个、三个或四个字节表示

UTF-16编码

UTF-16 是一种固定长度的编码方式

UTF-32 编码

UTF-32 是一种固定长度的编码方式,对于所有 Unicode 字符,使用四个字节表示

GBK 字符集

GBK 包含了 GB2312 字符集中的字符,同时还扩展了许多其他汉字字符和符号,共收录了 21,913 个字符。

GBK 编码是一种变长的编码方式,对于 ASCII 字符(码位范围为 0x00 0x7F ),使用一个字节表示,对于其他字符,使用两个字节表示。
GB2312 是一个较为简单的字符集,只包含了常用的汉字和符号,因此对于一些较为罕见的汉字和生僻字, GB2312 不能满足需求,现在已经逐渐被 GBK GB18030 等字符集所取代

编码方式 

浏览器百分号编码

URL 只能使用 ASCII 字符集来通过因特网进行发送。由于 URL 常常会包含 ASCII 集合之外的字符,URL 必须转换为有效的 ASCII 格式。

转化格式为:URL 编码使用 "%" 其后跟随两位的十六进制数来替换非 ASCII 字符

浏览器提交数据时默认会使用UrlEcode对内容进行编码,tomcat服务器默认会使用UrlDecode对内容进行解码,来解决中文乱码问题

测试一:

UrlEncode编码,对acsII码表中的大部分内容不会处理

//测试UrlEncode编码:
//1、编码:对acs码表中的大部分内容不会处理
String s ="abc123456.";
String encode = URLEncoder.encode(s, "UTF-8");
System.out.println("编码后: "+encode);
//2、解码
String decode = URLDecoder.decode(encode, "UTF-8");
System.out.println("解码后: "+decode);

测试二:使用UrlEcode解决中文乱码

//测试UrlEncode编码:
//1、编码:UTF-8的中文会转为三个%组成的字符串
String s ="http://localhost:8080?keyword=华为手机";
String encode = URLEncoder.encode(s, "UTF-8");
System.out.println("编码后: "+encode);
//2、解码
String decode = URLDecoder.decode(encode, "UTF-8");
System.out.println("解码后: "+decode);


Base64编码

jwt: jwt将载荷头 签名 使用Base64的算法处理后得到一个可读的字符串

base64:提供了64个字符
    a~z  A~Z   0~9   /  +       = 保留字符 不解析
    以后需要base64处理的字符串,每个字符只要可以转为64个字符的某一个就没有乱码
 
base64将数据转为字节数组,每3个字节重新分为一组,如果一组不足三个使用=补齐
再将三个字节拆分为4个字节,并在高位补充0

//1 byte = 8bit
         [ 1010 0101 ]  [ 1110 0101 ]  [ 0010 0101 ]
拆分后    [ 00 1010 01 ]  [ 00 01 1110  ]  [ 00 0101 00 ] [00 10 0101]

处理后每个字节最大是00 1111 11    取值范围一共有64种可能,每一个值对应base64提供的码表中的一个字符 a~z  A~Z   0~9   /  +

String s = "金三银四?";
byte[] encode = Base64.getEncoder().encode(s.getBytes("UTF-8"));
String s1 = new String(encode);
System.out.println("base64编码后:"+s1);
byte[] decode = Base64.getDecoder().decode(s1);
String s2 = new String(decode);
System.out.println("解码后: "+s2);

如果把字符串改为:

String s = "金三银四a";

如果把字符串改为:

String s = "金三银四ab";

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/503365.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GL绘制自定义线条2_手写曲线应用贝塞尔曲线

上一篇文章的曲线是由触摸点直接生成的&#xff0c;但触摸点并非连续的&#xff0c;而是离散的&#xff0c;而且屏幕触摸点采样的间隔时间其实不短&#xff0c;因此如果单纯只用触摸点生成OpenGL触摸曲线&#xff0c;在高速书写时会导致曲线看起来就像多个线段合起来一样&#…

为何ChatGPT一出现让巨头们都坐不住?

近几个月来&#xff0c;ChatGPT都是当仁不让的舆论话题。 上一次AI在全球范围内引起轰动&#xff0c;还是谷歌的AI机器人AlphaGO下棋战胜围棋世界冠军的时候。 ChatGPT的出现&#xff0c;让国内外几乎所有的科技巨头都坐立不安。 2月1日&#xff0c;谷歌母公司Alphabet首席执…

C++跨平台“点绘机” 代码解读

前言 球球大作战可以自定义皮肤&#xff0c;用画刷绘制。 想着用软件来绘制。 初次尝试&#xff0c;没有达成最终目的&#xff0c;不过也有很大收获。 仓库链接&#xff1a;https://github.com/sixsixQAQ/dolphin 问题 这个半成品&#xff0c;已经有了基本结构了&#xff…

高德地图api 地理编码(地址-->坐标)geocoder.getLocation在官方可以测试出结果,下载代码到本地却用不了 问题解决

问题 高德地图api 地理编码&#xff08;地址-->坐标&#xff09;功能&#xff0c;通过输入 地址信息 得到 经纬度信息。geocoder.getLocation在官方可以测试出结果&#xff0c;下载代码到本地却用不了。 官方示例测试&#xff0c;可以从地址得到坐标 下载官方代码本地运行却…

常见注意力机制解析

1.Squeeze-and-Excitation&#xff08;SE&#xff09; SE的主要思想是通过对输入特征进行压缩和激励&#xff0c;来提高模型的表现能力。具体来说&#xff0c;SE注意力机制包括两个步骤&#xff1a;Squeeze和Excitation。在Squeeze步骤中&#xff0c;通过全局平均池化操作将输…

【2023年Mathorcup杯数学建模竞赛C题】电商物流网络包裹应急调运与结构优化--完整作品分享

1.问题背景 2.论文摘要 为了应对电商物流网络中物流场地和线路电商物流网络中物流场地和线路上货量波动的情况&#xff0c; 设计合理的物流网络调整方案以保障物流网络的正常运行。本文运用 0-1 整数规划模型&#xff0c;多目标动 态规划模型&#xff0c;给出了问题的结果。 针…

深入讲解eMMC简介

1 eMMC是什么 eMMC是embedded MultiMediaCard的简称&#xff0c;即嵌入式多媒体卡,是一种闪存卡的标准&#xff0c;它定义了基于嵌入式多媒体卡的存储系统的物理架构和访问接口及协议&#xff0c;具体由电子设备工程联合委员会JEDEC订立和发布。它是对MMC的一个拓展&#xff0…

redi缓存使用

1、缓存的特征 第一个特征&#xff1a;在一个层次化的系统中&#xff0c;缓存一定是一个快速子系统&#xff0c;数据存在缓存中时&#xff0c;能避免每次从慢速子系统中存取数据。 第二个特征&#xff1a;缓存系统的容量大小总是小于后端慢速系统的&#xff0c;不可能把所有数…

GAMES101 计算机图形学 | 学习笔记 (上)

目录 环境安装什么是计算机图形学物体上点的坐标变换顺序齐次坐标光栅化如何判定一个点在三角形内光栅化填充三角形示例代码光栅化产生的问题 采样不足&#xff08;欠采样&#xff09;导致锯齿抗锯齿滤波算法 环境安装 1. C中安装opencv库 2. C中安装eigen库 3. C中安装open…

ChatGPT调教指北,技巧就是效率!

技巧就是效率 很多人都知道ChatGPT很火很强&#xff0c;几乎无所不能&#xff0c;但跨越了重重门槛之才有机会使用的时候却有些迷茫&#xff0c;一时间不知道如何使用它。如果你就是把他当作一个普通的智能助手来看待&#xff0c;那与小爱同学有什么区别&#xff1f;甚至还差劲…

热乎的面经——踏石留印

⭐️前言⭐️ 本篇文章记录博主面试北京某公司所记录的面经&#xff0c;希望能给各位带来帮助。 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论…

Origin如何绘制三维图形?

文章目录 0.引言1.使用矩阵簿窗口2.三维数据转换3.三维绘图4.三维曲面图5.三维XYY图6.三维符号、条状、矢量图7.等高线图 0.引言 因科研等多场景需要&#xff0c;绘制专业的图表&#xff0c;笔者对Origin进行了学习&#xff0c;本文通过《Origin 2022科学绘图与数据》及其配套素…

63.空白和视觉层级的实战应用

例如看我们之前的小网页&#xff1b; 这些标题的上下距离一样&#xff0c;这样让我们很容易对这些标题进行混淆&#xff0c;我们可以适当的添加一点空白 header, section {margin-bottom: 96px; }这样看上去似乎就好很多&#xff01; 除此之外&#xff0c;如我们之间学的空…

【line features】线特征

使用BinaryDescriptor接口提取线条并将其存储在KeyLine对象中&#xff0c;使用相同的接口计算每个提取线条的描述符&#xff0c;使用BinaryDescriptorMatcher确定从不同图像获得的描述符之间的匹配。 opencv提供接口实现 线提取和描述符计算 下面的代码片段展示了如何从图像中…

K8S相关核心概念

个人笔记&#xff1a; 要弄明白k8s的细节&#xff0c;需要知道k8s是个什么东西。它的主要功能&#xff0c;就是容器的调度--也就是把部署实例&#xff0c;根据整体资源的使用状况&#xff0c;部署到任何地方 注意任何这两个字&#xff0c;预示着你并不能够通过常规的IP、端口…

如何全面学习Object-C语言的语法知识 (Xmind Copilot生成)

网址&#xff1a;https://xmind.ai/login/ 登录后直接输入&#xff1a;如何全面学习Object-C语言的语法知识&#xff0c;就可以生成大纲 点击右上角的 按钮&#xff0c;可以显示md格式的问题&#xff0c;再点击生成全文&#xff0c;就可以生成所有内容了&#xff0c; 还有这个…

CentOS7/8 安装 5+ 以上的Linux kernel

CentOS以稳定著称&#xff0c;稳定在另外一方面就是保守。所以CentOS7还在用3.10&#xff0c;CentOS8也才是4.18。而当前最新的Linux Kernel都更新到6.0 rc3了。其他较新的发行版都用上了5.10的版本。本文简单介绍如何在CentOS7、8上直接安装5.1以上版本的第三方内核。 使用ted…

5.8晚间黄金行情走势分析及短线交易策略

近期有哪些消息面影响黄金走势&#xff1f;本周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周一亚洲时段&#xff0c;现货黄金小幅反弹&#xff0c;目前交投于2024.3美元/盎司附近&#xff0c;一方面是金价上周五守住了 2000 整数关口&#xff0c;逢低买盘涌…

java环境Springboot框架中配置使用GDAL,并演示使用GDAL读取shapefile文件

GDAL是应用广泛的空间数据处理库&#xff0c;可以处理几何、栅格数据&#xff0c;Springboot是常用的JAVA后端开发框架。本文讲解如何在Springboot中配置使用GDAL。本文示例中使用的GDAL版本为3.4.1&#xff08;64位&#xff09; 图1 GDAL读取shp效果 一、部署GDAL类库 将GDA…

什么是点对点传输?什么是点对多传输

点对点技术&#xff08;peer-to-peer&#xff0c; 简称P2P&#xff09;又称对等互联网络技术&#xff0c;是一种网络新技术&#xff0c;依赖网络中参与者的计算能力和带宽&#xff0c;而不是把依赖都聚集在较少的几台服务器上。P2P网络通常用于通过Ad Hoc连接来连接节点。这类网…