【安全】加密算法原理與實戰

為了理解SSL/TLS原理,大家需要掌握一些加密算法的基礎知識。當然,這不是為了讓大家成為密碼學專家,所以只需對基礎的加密算法有一些了解即可。基礎的加密算法主要有哈希(Hash,或稱為散列)?、對稱加密(Symmetric Cryptography)、非對稱加密(Asymmetric Cryptography)、數字簽名(Digital Signature)。

哈希單向加密算法原理與實戰

哈希算法(或稱為散列算法)比較簡單,就是為待加密的任意大小的信息(如字符串)生成一個固定大小(比如通過MD5加密之后是32個字符)的字符串摘要。常用的哈希算法有MD5、SHA1、SHA-512等。哈希是不可逆的加密技術,一些數據一旦通過哈希轉換為其他形式,源數據將永遠無法恢復。

在哪些場景下使用哈希加密呢?一般來說,在用戶注冊的時候,服務端保存用戶密碼的時候會將明文密碼的哈希密碼存儲在數據庫中,而不是直接存儲用戶的明文密碼。當用戶下次登錄時,會對用戶的登入密碼(明文)使用相同的哈希算法進行處理,并將哈希結果與來自數據庫的哈希密碼進行匹配,如果是相同的,那么用戶將登錄成功,否則用戶將登錄失敗。

哈希加密也稱為單向哈希加密,是通過對不同輸入長度的信息進行哈希計算得到固定長度的輸出,是單向、不可逆的。所以,即使保存用戶密碼的數據庫被攻擊,也不會造成用戶的密碼泄漏。

最常見的哈希算法為MD5(Message-Digest Algorithm 5,信息-摘要算法5)?,也是計算機廣泛使用的哈希算法之一。主流編程語言普遍都提供MD5實現,MD5的前身有MD2、MD3和MD4。
MD5將輸入的不定長度信息經過程序流程生成四個32位(Bit)數據,最后聯合起來輸出一個固定長度128位的摘要,基本處理流程包括求余、取余、調整長度、與鏈接變量進行循環運算等,最終得出結果。

除了MD5, Java還提供了SHA1、SHA256、SHA512等哈希摘要函數的實現。除了在算法上有些差異之外,這些哈希函數的主要不同在于摘要長度,MD5生成的摘要是128位,SHA1生成的摘要是160位,SHA256生成的摘要是256位,SHA512生成的摘要是512位。

SHA-1與MD5的最大區別在于其摘要比MD5摘要長32位(相當于長4字節,轉換十六進制后比MD5多8個字符)?。對SHA-1強行攻擊的強度比對MD5攻擊的強度要大。但是SHA-1哈希過程的循環步驟比MD5多,且需要的緩存大,因此SHA-1的運行速度比MD5慢。

以下代碼使用Java提供的MD5、SHA1、SHA256、SHA512等哈希摘要函數生成哈希摘要(哈希加密結果)并進行驗證的案例:


//省略import
public class HashCrypto
{/*** 哈希單向加密測試用例*/public static String encrypt(String plain){StringBuffer md5Str = new StringBuffer(32);try{/*** MD5*///MessageDigest md = MessageDigest.getInstance("MD5");/*** SHA-1*///MessageDigest md = MessageDigest.getInstance("SHA-1");/*** SHA-256*///MessageDigest md = MessageDigest.getInstance("SHA-256");/*** SHA-512*/MessageDigest md = MessageDigest.getInstance("SHA-512");String charset = "UTF-8";byte[] array = md.digest(plain.getBytes(charset));for (int i = 0; i < array.length; i++){//轉成十六進制字符串String hexString = Integer.toHexString((0x000000FF & array[i]) | 0xFFFFFF00);log.debug("hexString: {}, 第6位之后: {}",hexString, hexString.substring(6));md5Str.append(hexString.substring(6));}} catch (Exception ex){ex.printStackTrace();}return md5Str.toString();}public static void main(String[] args){//原始的明文字符串,也是需要加密的對象String plain = "123456";//使用哈希函數加密String cryptoMessage = HashCrypto.encrypt(plain);log.info("cryptoMessage:{}", cryptoMessage);//驗證String cryptoMessage2 = HashCrypto.encrypt(plain);log.info("驗證 {},\n是否一致:{}", cryptoMessage2,cryptoMessage.equals(cryptoMessage2));//驗證2String plainOther = "654321";String cryptoMessage3 = HashCrypto.encrypt(plainOther);log.info("驗證 {},\n是否一致:{}", cryptoMessage3,cryptoMessage.equals(cryptoMessage3));}
}

對稱加密算法原理與實戰

對稱加密(Symmetric Cryptography)指的是客戶端自己封裝一種加密算法,將給服務端發送的數據進行加密,并且將數據加密的方式(密鑰)發送給密文,服務端收到密鑰和數據,用密鑰進行解密。

在這里插入圖片描述
對稱加密:使用同一個密鑰加密和解密,優點是速度快;但是它要求共享密鑰,缺點是密鑰管理不方便、容易泄露。

常見的對稱加密算法有DES、AES等。DES加密算法出自IBM的數學研究,被美國政府正式采用之后開始廣泛流傳,但是近些年來使用越來越少,因為DES使用56位密鑰,以現代計算能力24小時內即可被破解。雖然如此,但是在對安全要求不高的應用中,還是可以使用DES加密算法。

下面是一段使用Java語言編寫的進行DES加密的演示代碼:


//省略import
public class DESCrypto
{/*** 對稱加密*/public static  byte[] encrypt(byte[] data, String password) {try{SecureRandom random = new SecureRandom();//使用密碼,創建一個密鑰描述符DESKeySpec desKey = new DESKeySpec(password.getBytes());//創建一個密鑰工廠,然后用它把 DESKeySpec 密鑰描述符實例轉換成密鑰SecretKeyFactory keyFactory =SecretKeyFactory.getInstance("DES");//通過密鑰工程生成密鑰SecretKey secretKey = keyFactory.generateSecret(desKey);//Cipher對象實際完成加密操作Cipher cipher = Cipher.getInstance("DES");//用密鑰初始化Cipher對象cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);//為數據執行加密操作return cipher.doFinal(data);}catch(Throwable e){e.printStackTrace();}return null;}/*** 對稱解密*/public static byte[] decrypt(byte[] cryptData,String password){//DES算法要求有一個可信任的隨機數源SecureRandom random = new SecureRandom();//創建一個 DESKeySpec 密鑰描述符對象DESKeySpec desKey = new DESKeySpec(password.getBytes());//創建一個密鑰工廠SecretKeyFactory keyFactory =SecretKeyFactory.getInstance("DES");//將 DESKeySpec 對象轉換成 SecretKey 對象SecretKey secretKey = keyFactory.generateSecret(desKey);//Cipher對象實際完成解密操作Cipher cipher = Cipher.getInstance("DES");//用密鑰初始化Cipher對象cipher.init(Cipher.DECRYPT_MODE, secretKey, random);//真正開始解密操作return cipher.doFinal(cryptData);}public static void main(String args[]) {//待加密內容String str = "123456";//密碼長度要是8的倍數String password = "12345678";byte[] result = DESCrypto.encrypt(str.getBytes(),password);log.info("str:{} 加密后:{}",str,new String(result));//直接將如上內容解密try {byte[] decryResult = DESCrypto.decrypt(result, password);log.info("解密后:{}",new String(decryResult));} catch (Exception e1) {e1.printStackTrace();}}
}

非對稱加密算法原理與實戰

非對稱加密算法(Asymmetric Cryptography)又稱為公開密鑰加密算法,需要兩個密鑰:一個稱為公開密鑰(公鑰)?;另一個稱為私有密鑰(私鑰)?。公鑰與私鑰需要配對使用,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密;如果使用私鑰對數據加密,那么需要用對應的公鑰才能解密。由于加解密使用不同的密鑰,因此這種算法為非對稱加密算法。
在這里插入圖片描述
非對稱加密算法的優點是密鑰管理很方便,缺點是速度慢。典型的非對稱加密算法有RSA、DSA等。

下面是一段使用Java代碼進行RSA加密的演示代碼:


//省略import
/*** RSA 非對稱加密算法*/
@Slf4j
public class RSAEncrypt
{/*** 指定加密算法為RSA*/private static final String ALGORITHM = "RSA";/*** 常量,用來初始化密鑰長度*/private static final int KEY_SIZE = 1024;/*** 指定公鑰存放文件*/private static final String PUBLIC_KEY_FILE =SystemConfig.getKeystoreDir() + "/PublicKey";/*** 指定私鑰存放文件*/private static final String PRIVATE_KEY_FILE =SystemConfig.getKeystoreDir() + "/PrivateKey";/*** 生成密鑰對*/protected static void generateKeyPair() throws Exception{/*** 為RSA算法創建一個KeyPairGenerator對象*/KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(ALGORITHM);/*** 利用上面的密鑰長度初始化這個KeyPairGenerator對象*/keyPairGenerator.initialize(KEY_SIZE);/** 生成密鑰對 */KeyPair keyPair = keyPairGenerator.generateKeyPair();/** 得到公鑰 */PublicKey publicKey = keyPair.getPublic();/** 得到私鑰 */PrivateKey privateKey = keyPair.getPrivate();ObjectOutputStream oos1 = null;ObjectOutputStream oos2 = null;try{log.info("生成公鑰和私鑰,并且寫入對應的文件";File file = new File(PUBLIC_KEY_FILE);if (file.exists()){log.info("公鑰和私鑰已經生成,不需要重復生成,path:{}", PUBLIC_KEY_FILE);return;}/** 用對象流將生成的密鑰寫入文件 */log.info("PUBLIC_KEY_FILE 寫入:{}", PUBLIC_KEY_FILE);oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));log.info("PRIVATE_KEY_FILE 寫入:{}", PRIVATE_KEY_FILE);oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));oos1.writeObject(publicKey);oos2.writeObject(privateKey);} catch (Exception e){throw e;} finally{/** 清空緩存,關閉文件輸出流 */IOUtil.closeQuietly(oos1);IOUtil.closeQuietly(oos2);}}/*** 加密方法,使用公鑰加密* @param plain 明文數據*/public static String encrypt(String plain) throws Exception{//從文件加載公鑰Key publicKey = loadPublicKey();/** 得到Cipher對象,來實現對源數據的RSA加密 */Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] b = plain.getBytes();/** 執行加密操作 */byte[] b1 = cipher.doFinal(b);BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(b1);}/*** 從文件加載公鑰*/public static PublicKey loadPublicKey() throws Exception{PublicKey publicKey=null;ObjectInputStream ois = null;try{log.info("PUBLIC_KEY_FILE 讀取:{}", PUBLIC_KEY_FILE);/** 讀出文件中的公鑰 */ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));publicKey = (PublicKey) ois.readObject();} catch (Exception e){throw e;} finally{IOUtil.closeQuietly(ois);}return publicKey;}//方法:對密文解密,使用私鑰解密public static String decrypt(String crypto) throws Exception{PrivateKey privateKey = loadPrivateKey();/** 得到Cipher對象,對已用公鑰加密的數據進行RSA解密 */Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, privateKey);BASE64Decoder decoder = new BASE64Decoder();byte[] b1 = decoder.decodeBuffer(crypto);/** 執行解密操作 */byte[] b = cipher.doFinal(b1);return new String(b);}/*** 從文件加載私鑰* @throws Exception*/public static PrivateKey loadPrivateKey() throws Exception{PrivateKey privateKey;ObjectInputStream ois = null;try{log.info("PRIVATE_KEY_FILE 讀取:{}", PRIVATE_KEY_FILE);/** 讀出文件中的私鑰 */ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));privateKey = (PrivateKey) ois.readObject();} catch (Exception e){e.printStackTrace();throw e;} finally{IOUtil.closeQuietly(ois);}return privateKey;}public static void main(String[] args) throws Exception{//生成密鑰對generateKeyPair();//待加密內容String plain = "123";//公鑰加密String dest = encrypt(plain);log.info("{} 使用公鑰加密后:\n{}", plain, dest);//私鑰解密String decrypted = decrypt(dest);log.info(" 使用私鑰解密后:\n{}", decrypted);}
}

非對稱加密算法包含兩種密鑰,其中的公鑰本來是公開的,不需要像對稱加密算法那樣將私鑰給對方,對方解密時使用公開的公鑰即可,大大地提高了加密算法的安全性。退一步講,即使不法之徒獲知了非對稱加密算法的公鑰,甚至獲知了加密算法的源碼,只要沒有獲取公鑰對應的私鑰,也是無法進行解密的。

數字簽名原理與實戰

數字簽名(Digital Signature)是確定消息發送方身份的一種方案。在非對稱加密算法中,發送方A通過接收方B的公鑰將數據加密后的密文發送給接收方B, B利用私鑰解密就得到了需要的數據。這里還存在一個問題,接收方B的公鑰是公開的,接收方B收到的密文都是使用自己的公鑰加密的,那么如何檢驗發送方A的身份呢?

一種非常簡單的檢驗發送方A身份的方法為:發送方A可以利用A自己的私鑰進行消息加密,然后B利用A的公鑰來解密,由于私鑰只有A知道,接收方只要解密成功,就可以確定消息來自A而不是其他地方。

數字簽名的原理就基于此,通常為了證明發送數據的真實性,利用發送方的私鑰對待發送的數據生成數字簽名。

數字簽名的流程比較簡單,首先通過哈希函數為待發數據生成較短的消息摘要,然后利用私鑰加密該摘要,所得到的摘要密文基本上就是數字簽名。發送方A將待發送數據以及數字簽名一起發送給接收方B,接收方B收到之后使用A的公鑰校驗數字簽名,如果校驗成功,就說明內容來自發送方A,否則為非法內容。

數字簽名的大致流程如圖12-7所示。
在這里插入圖片描述
Java為數字簽名提供了良好的支持,java.security.Signature接口提供了數字簽名的基本操作API, Java規范要求各JDK版本需要提供表12-2中所列出的標準簽名實現。

在這里插入圖片描述
下面是一段使用JSHA512withRSA算法實現數字簽名的Java演示代碼:

package com.crazymakercircle.secure.crypto;
//省略import
/*** RSA簽名演示*/
@Slf4j
public class RSASignDemo
{/*** RSA簽名** @param data   待簽名的字符串* @param priKey RSA私鑰字符串* @return 簽名結果* @throws Exception 簽名失敗則拋出異常*/public byte[] rsaSign(byte[] data, PrivateKey priKey)throws SignatureException{try{Signature signature = Signature.getInstance("SHA512withRSA");signature.initSign(priKey);signature.update(data);byte[] signed = signature.sign();return signed;} catch (Exception e){throw new SignatureException("RSAcontent = " + data+ "; charset = ", e);}}/*** RSA驗簽* @param data   被簽名的內容* @param sign   簽名后的結果* @param pubKey RSA公鑰* @return 驗簽結果*/public boolean verify(byte[] data, byte[] sign, PublicKey pubKey)throws SignatureException{try{Signature signature = Signature.getInstance("SHA512withRSA");signature.initVerify(pubKey);signature.update(data);return signature.verify(sign);} catch (Exception e){e.printStackTrace();throw new SignatureException("RSA驗證簽名[content = " + data+"; charset = " + "; signature = " + sign + "]發生異常!", e);}}/*** 私鑰*/private PrivateKey privateKey;/*** 公鑰*/private PublicKey publicKey;/*** 加密過程* @param publicKey     公鑰* @param plainTextData 明文數據* @throws Exception 加密過程中的異常信息*/public byte[] encrypt(PublicKey publicKey, byte[] plainTextData)throws Exception{if (publicKey == null){throw new Exception"加密公鑰為空, 請設置";}Cipher cipher = null;try{cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output = cipher.doFinal(plainTextData);return output;} catch (NoSuchAlgorithmException e){throw new Exception"無此加密算法";}}/*** 解密過程* @param privateKey 私鑰* @param cipherData 密文數據* @return 明文* @throws Exception 解密過程中的異常信息*/public byte[] decrypt(PrivateKey privateKey, byte[] cipherData){if (privateKey == null){throw new Exception"解密私鑰為空, 請設置";}Cipher cipher = null;try{cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output = cipher.doFinal(cipherData);return output;} catch (NoSuchAlgorithmException e){throw new Exception"無此解密算法";}}/*** Main 測試方法* @param args*/public static void main(String[] args) throws Exception{RSASignDemo RSASignDemo = new RSASignDemo();//加載公鑰RSASignDemo.publicKey = RSAEncrypt.loadPublicKey();//加載私鑰RSASignDemo.privateKey = RSAEncrypt.loadPrivateKey();//測試字符串String sourceText = "12312";try{log.info("加密前的字符串為:{}", sourceText);//公鑰加密byte[] cipher = RSASignDemo.encrypt(RSASignDemo.publicKey, sourceText.getBytes());//私鑰解密byte[] decryptText = RSASignDemo.decrypt(RSASignDemo.privateKey, cipher);log.info("私鑰解密的結果是:{}", new String(decryptText));//字符串生成簽名byte[] rsaSign = RSASignDemo.rsaSign(sourceText.getBytes(), RSASignDemo.privateKey);//簽名驗證Boolean succeed = RSASignDemo.verify(sourceText.getBytes(),rsaSign, RSASignDemo.publicKey);log.info("字符串簽名為:\n{}", byteToHex(rsaSign));log.info("簽名驗證結果是:{}", succeed);String fileName =IOUtil.getResourcePath("/system.properties");byte[] fileBytes = readFileByBytes(fileName);//文件簽名驗證byte[] fileSign =RSASignDemo.rsaSign(fileBytes, RSASignDemo.privateKey);log.info("文件簽名為:\n{}" , byteToHex(fileSign));//文件簽名保存String signPath =SystemConfig.getKeystoreDir() + "/fileSign.sign";ByteUtil.saveFile(fileSign,signPath );Boolean verifyOK = RSASignDemo.verify(fileBytes, fileSign, RSASignDemo.publicKey);log.info("文件簽名驗證結果是:{}", verifyOK);//讀取驗證文件byte[] read = readFileByBytes(signPath);log.info("讀取文件簽名:\n{}" , byteToHex(read));verifyOK= RSASignDemo.verify(fileBytes, read, RSASignDemo.publicKey);log.info("讀取文件簽名驗證結果是:{}", verifyOK);} catch (Exception e){System.err.println(e.getMessage());}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76369.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76369.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76369.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 優化教程:讓你的數據庫飛起來

文章目錄 前言一、數據庫設計優化1. 合理設計表結構2. 范式化與反范式化3. 合理使用索引 二、查詢優化1. 避免使用 SELECT *2. 優化 WHERE 子句3. 優化 JOIN 操作 三、服務器配置優化1. 調整內存分配2. 調整并發參數3. 優化磁盤 I/O 四、監控與分析1. 使用 EXPLAIN 分析查詢語句…

LangChain4j(1):初步認識Java 集成 LLM 的技術架構

LangChain 作為構建具備 LLM 能力應用的框架&#xff0c;雖在 Python 領域大放異彩&#xff0c;但 Java 開發者卻只能望洋興嘆。LangChain4j 正是為解決這一困境而誕生&#xff0c;它旨在借助 LLM 的強大效能&#xff0c;增強 Java 應用&#xff0c;簡化 LLM 功能在Java應用中的…

Linux服務器安裝百度飛槳3.0(pip docker)

Linux安裝部署百度飛槳3.0 1.官方文檔指引2.確認服務器型號2.1 確認Python版本2.2 確認pip是否安裝2.3 確認計算平臺 3.本機安裝&#xff08;基于通過 pip 安裝&#xff09;3.1 下載安裝 PaddlePaddle3.2 安裝PaddleX3.2.1 安裝PaddleX3.2.2 命令行規范3.2.3 運行示例3.2.4 查看…

Spring Boot 自動加載流程詳解

前言 Spring Boot 是一個基于約定優于配置理念的框架&#xff0c;它通過自動加載機制大大簡化了開發者的配置工作。本文將深入探討 Spring Boot 的自動加載流程&#xff0c;并結合源碼和 Mermaid 圖表進行詳細解析。 一、Spring Boot 自動加載的核心機制 Spring Boot 的自動加…

2025年危化品安全管理人員備考指南|智能題庫+核心考點解析

作為危化品生產單位安全管理人員&#xff08;主要負責人&#xff09;&#xff0c;考試內容主要涵蓋三大模塊&#xff1a; 法律法規體系 《安全生產法》修訂要點&#xff08;2023版&#xff09; 危險化學品重大危險源辨識標準&#xff08;GB 18218&#xff09; 最新《化工過…

如何優雅使用 ReentrantLock 進行加解鎖:避免常見坑點,提高代碼可維護性

引言&#xff1a;鎖的基本概念和問題 在多線程編程中&#xff0c;為了確保多個線程在訪問共享資源時不會發生沖突&#xff0c;我們通常需要使用 鎖 來同步對資源的訪問。Java 提供了不同的鎖機制&#xff0c;其中 ReentrantLock 是一種最常用且功能強大的鎖&#xff0c;它屬于…

Redhat紅帽 RHCE8.0認證體系課程

課程大小&#xff1a;7.7G 課程下載&#xff1a;https://download.csdn.net/download/m0_66047725/90546064 更多資源下載&#xff1a;關注我 紅帽企業 Linux 系統的管理技能已經成為現代數據中心的核心競爭力。 Linux 在支持混合云、跨物理服務器、虛機、私有云和公共云計…

Shell腳本編程

目錄 1. Shell腳本概述 什么是Shell&#xff1f; Shell的作用 常見的Shell類型 2. 環境搭建與安裝 Linux系統 macOS系統 Windows系統 3.安裝并配置Zsh&#xff08;macOS/Linux&#xff09; 4. Shell基礎語法 變量與數據類型 輸入交互 5. Shell腳本進階 進程管理 …

學生管理系統(Python)

運行結果&#xff1a; 源代碼&#xff1a; """ 項目&#xff1a;類似于學生管理系統---增刪改查 """ #封裝一個學生類 import random class Student: def __init__(self,stuid,name,score): self.stuid stuid self.name name self.score …

電商素材革命:影刀RPA魔法指令3.0驅動批量去水印,實現秒級素材凈化

本文 去除水印實操視頻展示電商圖片水印處理的困境?影刀 RPA 魔法指令 3.0 強勢登場?利用魔法指令3.0兩步實現去除水印操作關于影刀RPA 去除水印實操視頻展示 我們這里選擇了4張小紅書里面比較帥氣的圖片&#xff0c;但凡用過小紅書的都知道&#xff0c;小紅書右下角是會有小…

Seq2Seq - GRU補充講解

nn.GRU 是 PyTorch 中實現門控循環單元&#xff08;Gated Recurrent Unit, GRU&#xff09;的模塊。GRU 是一種循環神經網絡&#xff08;RNN&#xff09;的變體&#xff0c;用于處理序列數據&#xff0c;能夠更好地捕捉長距離依賴關系。 ?重點掌握輸入輸出部分輸入張量&#…

設計模式-觀察者模式和發布訂閱模式區別

文章目錄 其他不錯的文章 二者有類似的地方&#xff0c;也有區別。 引用的文章說的已經比較清楚了&#xff0c;這里只列出對比圖。 對比點觀察者模式發布訂閱模式中間人角色無事件中心&#xff0c;觀察者直接訂閱目標有事件中心&#xff0c;發布者與訂閱者通過事件中心通信關系…

【SQL】基于多源SQL 去重方法對比 -- 精華版

【SQL】基于SQL 去重方法對比 -- 精華版 一、引言二、基于SQL去重方法完整對比1. MySQL去重方法及優劣勢1.1 ?DISTINCT關鍵字1.2 GROUP BY子句1.3 UNION系列操作1.4 子查詢 自關聯 2. Hive去重方法及優劣勢2.1 DISTINCT關鍵字2.2 ?GROUP BY子句2.3 ?ROW_NUMBER窗口函數2.4 …

電腦命名配置很高,為什么運行軟件特別卡

估計很多同學都碰見過這種情況&#xff0c;以我的Redmi G為例&#xff0c;I9-14待CPU&#xff0c;又換了一條內存條&#xff0c;現有配置I9-14900&#xff0c;40G內存5200MT/s&#xff0c;4060顯卡&#xff0c;為啥運行兩個辦公軟件就卡的不行&#xff0c;風扇狂轉&#xff0c;…

Spring Boot默認注冊的轉換器列表及其功能說明。這些轉換器使得控制器方法可以直接接收Integer、Long、Date等類型參數,無需手動實現轉換

以下是Spring Boot默認注冊的轉換器列表及其功能說明。這些轉換器使得控制器方法可以直接接收Integer、Long、Date等類型參數&#xff0c;無需手動實現轉換&#xff1a; 默認轉換器列表及功能 1. 基礎類型轉換器 轉換器名稱功能示例場景StringToIntegerConverter將字符串轉換…

chrome提示https不安全, 不能記住賬號密碼怎么辦? 可以利用js輸入賬號

背景: 在內網搭建的服務, 由于https證書問題, 可能會被chrome瀏覽器提示不安全 此時, 默認的記住賬號密碼功能就無法使用, 那么此時只能手動輸入了嗎? 想到了幾種方案 1.利用外置軟件, 模擬按鍵輸入(比如按鍵精靈, 缺點是依賴外部軟件, 運行速度也慢, 且執行時占用了輸入焦…

探秘Transformer系列之(25)--- KV Cache優化之處理長文本序列

探秘Transformer系列之&#xff08;25&#xff09;— KV Cache優化之處理長文本序列 文章目錄 探秘Transformer系列之&#xff08;25&#xff09;--- KV Cache優化之處理長文本序列0x00 概述0x01 優化依據1.1 稀疏性1.2 重要性1.3 小結 0x02 稀疏化1.1 分類1.2 靜態稀疏化1.2.1…

【開發經驗】結合實際問題解決詳述HTTPS通信過程

最近的開發調試過程中涉及到了HTTPS發送與接收&#xff0c;遇到實際問題才發現對這部分尚屬于一知半解。結合實際問題的解決過程來詳細整理以下HTTPS通信過程。 需要調試的功能為BMC作為客戶端向搭建好的Web服務器發送HTTPS請求&#xff0c;Web服務器負責接收處理發送過來的HT…

【Android】Android Activity 橫屏設置詳解及常見異常問題解決方法匯總

在 Android 開發中&#xff0c;我們經常需要控制 Activity 的屏幕方向&#xff0c;例如視頻播放、游戲、VR/AR 應用等場景通常希望默認橫屏顯示。本文將講解如何通過 Manifest 配置 和 Java/Kotlin 代碼 設置橫屏顯示&#xff0c;并分析常見設置無效的原因與解決方法。 一、通過…

文件相關:echo重定向管道命令擴展詳解

一、echo 文字內容 echo 會在終端中顯示參數指定的文字&#xff0c;通常會和 重定向 聯合使用 二、重定向 > 和 >> Linux 允許將命令執行結果 重定向到一個 文件將本應顯示在終端上的內容 輸出 / 追加 到指定文件中 其中&#xff1a; >表示輸出&#xff0c;會覆…