java案例RSA分段加密解密,签名验签,公钥加密私钥解密,私钥加密公钥解密,解密乱码怎么解决

news2024/11/19 22:42:41

一. 原理

非对称加密算法是一种密钥的保密方法。
非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将公钥公开,需要向甲方发送信息的其他角色(乙方)使用该密钥(甲方的公钥)对机密信息进行加密后再发送给甲方;甲方再用自己私钥对加密后的信息进行解密。甲方想要回复乙方时正好相反,使用乙方的公钥对数据进行加密,同理,乙方使用自己的私钥来进行解密。

二. 场景

多用于银行等安全级别较高系统

三. 实现原理

整体过程描述:首先通过RSA生成工具生成公玥密钥,分发给各系统,各系统在调接口时,利用私约生成签名,公玥加密数据,被调用方利用公玥验签,私约解密数据。

四.java案例

package com.atguigu.springcloud.util.interrup;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.net.URLDecoder;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class RSAUtil04 {
    /**
     * 加密算法RSA
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;

    /**
     * 生成密钥对(公钥和私钥)
     *
     * @return
     * @throws Exception
     */
    public static Map<String, Object> genKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    /**
     * 获取公钥字符串
     *
     * @param keyMap 密钥对
     * @return 公钥字符串
     * @throws Exception 异常
     */
    public static String getPublicKeyStr(Map<String, Object> keyMap) throws Exception {
        //获得map中的公钥对象 转为key对象
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        //编码返回字符串
        return encryptBASE64(key.getEncoded());
    }

    /**
     * 获取私钥字符串
     *
     * @param keyMap 密钥对
     * @return 私钥字符串
     * @throws Exception 异常
     */
    public static String getPrivateKeyStr(Map<String, Object> keyMap) throws Exception {
        //获得map中的私钥对象 转为key对象
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        //编码返回字符串
        return encryptBASE64(key.getEncoded());
    }

    /**
     * 将byte[]进行Base64编码
     *
     * @param key 待编码的byte[]
     * @return 编码后的字符串
     */
    public static String encryptBASE64(byte[] key) {
        return Base64.getMimeEncoder().encodeToString(key);
    }
    /**
     * 用私钥对信息生成数字签名
     *
     * @param data 已加密数据
     * @param privateKey 私钥(BASE64编码)
     *
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        byte[] keyBytes = Base64Utils.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(data);
        return Base64Utils.encode(signature.sign());
    }

    /**
     * 校验数字签名
     *
     * @param data 已加密数据
     * @param publicKey 公钥(BASE64编码)
     * @param sign 数字签名
     *
     * @return
     * @throws Exception
     *
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicK);
        signature.update(data);
        return signature.verify(Base64Utils.decode(sign));
    }

    /**
     * 私钥解密
     *
     * @param encryptedData 已加密数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * 公钥解密
     *
     * @param encryptedData 已加密数据
     * @param publicKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * 公钥加密
     *
     * @param data 源数据
     * @param publicKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * 私钥加密
     *
     * @param data 源数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * 获取私钥
     *
     * @param keyMap 密钥对
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return Base64Utils.encode(key.getEncoded());
    }

    /**
     * 获取公钥
     *
     * @param keyMap 密钥对
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return Base64Utils.encode(key.getEncoded());
    }

    public static void main(String[] args) {
        try {
            String json = "{\n" +
                    "    \"successful\": false,\n" +
                    "    \"code\": 1010,\n" +
                    "    \"message\": \"参数【_identificationId】没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限没有该字段查询权限\",\n" +
                    "    \"timestamp\": 1695881640402,\n" +
                    "    \"requestId\": \"4d8a793df32141d1bf6fb0a2bd527fa8\"\n" +
                    "}";
            byte[] data = json.getBytes();
            Map<String, Object> stringObjectMap = genKeyPair();
            String pubK = getPublicKeyStr(stringObjectMap);
            String priK = getPrivateKeyStr(stringObjectMap);

//

            System.out.println("---------------------------------公钥加密私钥解密-----------------------------------");
            // 获取签名
            String sign = RSAUtil04.sign(data, priK);
            boolean flag = RSAUtil04.verify(data, pubK, sign);

            byte[] sendByte = RSAUtil04.encryptByPublicKey(data, pubK);
            // 把加密数据转string
            // 这是实际接口中要发送的数据
            String sendStr = Base64Utils.encode(sendByte);
            System.out.println("encode1="+sendStr);
            // string转二进制
            byte[] sendBytes = Base64Utils.decode(sendStr);
            // 数据解密
            byte[] resultByte = new byte[0];

            resultByte = RSAUtil04.decryptByPrivateKey(sendBytes, priK);
            String resultStr = new String(resultByte);
            System.out.println("resultStr1="+resultStr);

            System.out.println("---------------------------------私钥加密公钥解密-----------------------------------");

            byte[] sendByte2 = RSAUtil04.encryptByPrivateKey(data, priK);
            // 把加密数据转string
            // 这是实际接口中要发送的数据
            String sendStr2 = Base64Utils.encode(sendByte2);
            System.out.println("encode2="+sendStr2);
            // string转二进制
            byte[] sendBytes2 = Base64Utils.decode(sendStr2);
            // 数据解密
            byte[] resultByte2 = new byte[0];

            resultByte2 = RSAUtil04.decryptByPublicKey(sendBytes2, pubK);
            String resultStr2 = new String(resultByte2);
            System.out.println("resultStr2="+resultStr2);


            System.out.println("--------------------------用别人返回的密文公钥解密------------------------------");
            //密文
            String data2 = "HMoBWOOr2z7yTEl0O4lwkNzJM8ntzuSNfViIQfbM8vCoeaVCvVub41n51QMsPgklD2cMa17dFp3SpkUGwRz2f7c7ckA85RYZm0UQtUB7yjYGNwKdiyGnHOu4WVmL3SoOFC2gYJWV0gznsiGOS02WJ3FRLNzneW+tCk1RA7jCDx+WL1f+K7AFklOFRAoJAqFq7VkPTaRNyjDFY4VYZwUGR+KxDPwvGJctaCRwvcZ0DmhSTYoKrqCbrUlV62WcUO4WPjVMphil8V8rLZ+E5xL675a75MTLhpw/QEUMfXOtpDz3YTMWvYrfzV/un/TPnuxVseEmQDjamJ1sOD4VPesY34whHS+82n2ds5NQZG7IzgQ3maPMbDjWHk4CNFj00LWFAia4dlIs/tbiPQBMkQx33jwmcc5uI3PUEhVg+lJIuJKEbr7R9oKBUGbimhmE8C6XlK7kKw97cisWX5tJQsnHpMKwr+tZy7pY+lZX/AT8Ek1624aHx4jDU7MHdGbv1zuJS95AziLce7GEUExeRvs93Mj3KHZgD6rVO+KcU5JlfE2Wj176iuaWRjAtib0neZpMRqTmH4FZdFPZRfP1YpWrZrguwyeRhWjEs+h6Khf6QBQRRxdcOf6OrJz1ykP7Eq7+OoTjqSViq5ARfhqjWbwyUwVZ/JMWa3DAxCR9m+xYlmI=";
            byte[] sendBytes4 = Base64Utils.decode(data2);
            // 数据解密
            byte[] resultByte4 = new byte[0];
            String pubk2="***公钥***";
            resultByte4 = RSAUtil04.decryptByPublicKey(sendBytes4, pubk2);
            String resultStr4 = new String(resultByte4);
            //加上下面这行解密就不会出现乱码原因:分段解密的时候汉字 字节代表3个字节,在解密最大长度分界如果3个字节被分隔成了两段转成string就会乱码了
            resultStr4 = URLDecoder.decode(resultStr4);
            System.out.println("resultStr4="+resultStr4);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

五.发现的问题:对方返回的密文在本地使用公钥解密时乱码

效果:
在这里插入图片描述
返回值:
在这里插入图片描述

分段解密的时候汉字 字节代表3个字节,在解密最大长度分界如果3个字节被分隔成了两段转成string就会乱码了
加上下面这样代码就OK
resultStr4 = URLDecoder.decode(resultStr4);
在这里插入图片描述

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

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

相关文章

Docker基础操作命令演示

Docker中的常见命令&#xff0c;可以参考官方文档&#xff1a;https://docs.docker.com/engine/reference/commandline/cli/ 1、常见命令介绍 其中&#xff0c;比较常见的命令有&#xff1a; 命令说明文档地址docker pull拉取镜像docker pulldocker push推送镜像到DockerReg…

Googleplay近期大量开发者二次验证问题与解决思路

近期谷歌play更新风控&#xff0c;开发者需要进行二次验证。9月份后大部分的开发者账号不论新老大部分都触发了二次验证风控&#xff0c;笔者目前整理了两个方向的解决方案。 老账号目前解决方案可以通过上传护照、身份证明、驾驶证或者租赁合同、水电费账单、信用卡账单、电话…

了解华为交换机路由器的基本命令

什么是CLI&#xff1a;使用户与设备交互的界面&#xff0c;用户输入对应的命令&#xff0c;设备会回复我们输入的内容&#xff0c;回车车后设备会执行对应命令&#xff0c;达到管理、配置、查看的目的。 CLI界面分为三种操作视图&#xff1a; 用户试图&#xff1a;设备登陆后…

基于阿基米德优化优化的BP神经网络(分类应用) - 附代码

基于阿基米德优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于阿基米德优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.阿基米德优化优化BP神经网络3.1 BP神经网络参数设置3.2 阿基米德优化算…

Java代码获取当天最晚时间写入数据库自动变为下一天的00:00:00

背景 有个需求要求将用户上传的年/月/日格式时间转为当天最晚时间23:59:59&#xff0c;例如上传2023/10/15&#xff0c;转换为2023/10/15 23:59:59&#xff0c;并将其存入数据库&#xff0c;数据库字段类型为datetime。 部分代码如下&#xff1a; public static Date getEndO…

游戏设计模式专栏(九):用装饰模式定制化游戏元素

点击上方亿元程序员关注和★星标 引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》&#xff0c;让糟糕的代码在潜移默化中升华&#xff0c;欢迎大家关注分享收藏订阅。 装饰模式是一种结构性设…

Qt6开发的网络通信工具(支持TCP和UDP)

1. 页面展示 1.2 通信展示 1.2.1 UDP 通信显示 注意&#xff1a;前面的R表示时接收消息&#xff0c;S表示的是发送消息。 1.2.2 TCP通信显示 注&#xff1a;勾选服务器后&#xff0c;出现客户端连接列表&#xff0c;可以群发消息和私发消息。 3. 程序下载 应用程序免费下载&a…

(2022|CVPR,无语言模型,StyleGAN2,CLIP,图文特征对齐)LAFITE:迈向文本到图像生成的无语言训练

LAFITE: Towards Language-Free Training for Text-to-Image Generation 公众号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 简介 2. 相关工作 3. LAFITE&#xff1a;一种无…

JDBC技术(java数据库连接技术)

引入&#xff1a;USB技术介绍 USB&#xff0c;是英文Universal Serial Bus&#xff08;通用串行总线&#xff09;的缩写&#xff0c;是一个外部总线标准&#xff0c;用于规范与外部设备的连接和通讯 USB是一个技术统称&#xff0c;有三部分组成 第一部分&#xff1a;USB的规范和…

深度学习电脑配置

目录 你真的需要这么一块阵列卡 你真的需要这么一块阵列卡 如何从硬件上保证数据安全&#xff1f;以下面这个 阵列卡 为例&#xff0c;它可以给硬盘组建磁盘阵列&#xff0c;其中用的比较多的是 RAID1 和 RAID5 。

【Linux】线程属性的定义如何修改线程属性(附图解与代码实现)

我们知道&#xff0c;在创建线程时&#xff0c;会用到pthread_create()函数 &#xff0c;我们来简单介绍一下该函数&#xff1a; pthread_create(线程的tid &#xff0c; 线程属性 &#xff0c; 工作函数名 &#xff0c; 函数需要的参数); 这篇博客要讲的线程属性&#xff0c…

卷积和反卷积的一些计算细节记录

一、卷积计算 多通道输入的情况 维度计算公式 参考&#xff1a; https://blog.csdn.net/qq_42596142/article/details/111467409 https://blog.csdn.net/v_july_v/article/details/51812459 https://www.cnblogs.com/wenshinlee/p/12591492.html 二、反卷积计算&#xff…

【音视频|ALSA】ALSA是什么?ALSA框架详细介绍

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

相似性搜索:第 5 部分--局部敏感哈希 (LSH)

SImilarity 搜索是一个问题&#xff0c;给定一个查询的目标是在所有数据库文档中找到与其最相似的文档。 一、介绍 在数据科学中&#xff0c;相似性搜索经常出现在NLP领域&#xff0c;搜索引擎或推荐系统中&#xff0c;其中需要检索最相关的文档或项目以进行查询。在大量数据中…

Linux常用命令——consoletype命令

在线Linux命令查询工具 consoletype 输出已连接的终端类型 补充说明 consoletype命令用于打印已连接的终端类型到标准输出&#xff0c;并能够检查已连接的终端是当前终端还是虚拟终端。 语法 consoletype实例 [rootlocalhost ~]# consoletype pty在线Linux命令查询工具

云原生场景下高可用架构的最佳实践

作者&#xff1a;刘佳旭&#xff08;花名&#xff1a;佳旭&#xff09;&#xff0c;阿里云容器服务技术专家 引言 随着云原生技术的快速发展以及在企业 IT 领域的深入应用&#xff0c;云原生场景下的高可用架构&#xff0c;对于企业服务的可用性、稳定性、安全性越发重要。通…

Springboot+vue的人事管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的人事管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的人事管理系统&#xff0c;采用M&#xff08;model…

2023年【四川省安全员B证】报名考试及四川省安全员B证考试内容

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 四川省安全员B证报名考试根据新四川省安全员B证考试大纲要求&#xff0c;安全生产模拟考试一点通将四川省安全员B证模拟考试试题进行汇编&#xff0c;组成一套四川省安全员B证全真模拟考试试题&#xff0c;学员可通过…

程序装载:“640K内存”真的不够用么?

目录 背景 程序装载面临的挑战 内存分段 内存分页 小结 背景 计算机这个行业的历史上有过很多成功的预言&#xff0c;最著名的自然是“摩尔定律”。当然免不了的也有很多“失败”的预测&#xff0c;其中一个最著名的就是&#xff0c;比尔盖茨在上世纪 80 年代说的“640K …

计网面试复习自用

五层&#xff1a; 应用层&#xff1a;应用层是最高层&#xff0c;负责为用户提供网络服务和应用程序。在应用层&#xff0c;用户应用程序与网络进行交互&#xff0c;发送和接收数据。典型的应用层协议包括HTTP&#xff08;用于网页浏览&#xff09;、SMTP&#xff08;用于电子邮…