首页 > 其他分享 >编码与加密(对称加密与非对称加密)

编码与加密(对称加密与非对称加密)

时间:2024-06-14 20:33:13浏览次数:21  
标签:编码 加密 密钥 哈希 ans 非对称 byte block

目录

编码与加密

  • 只记录作用和场景使用,不探索原理(哥们数学不好.jpg
  • demo都是golang实现的

Base64编码(可逆)

它的主要作用是将二进制数据转换为文本格式,从而便于在文本传输通道中传递。
因为传输二进制数据时候比如在http中要以可见字符传输,所以需要将二进制数据编码为可见字符。

  • 标准 Base64 里的 64 个可打印字符是 A-Za-z0-9+/

    编码后长度是(n+2)/3*4
  • 如果待编码内容的字节数不是 3 的整数倍,那需要进行一些额外的处理。
    • 如果最后剩下 1 个字节,那么将补 4 个 0 位,编码成 2 个 Base64 字符,然后补两个 =:
    • 如果最后剩下 2 个字节,那么将补 2 个 0 位,编码成 3 个 Base64 字符,然后补一个 =:
  • URL Safe Base64 编码
    在 URL 的应用场景中,因为标准 Base64 索引表中的 / 和 + 会被 URLEncoder 转义成 %XX 形式,但 % 是 SQL 中的通配符,直接用于数据库操作会有问题。此时可以采用 URL Safe 的编码器
    将 + 替换为 -
    将 / 替换为 _
ans := make([]byte, base64.StdEncoding.EncodedLen(len("abcd")))
base64.StdEncoding.Encode(ans,[]byte("abcs"))//编码
fmt.Println(string(ans))
ans2 := make([]byte, base64.StdEncoding.DecodedLen(len(ans)))
base64.StdEncoding.Decode(ans2,ans)//解码
fmt.Println(string(ans2))

十六进制编码(hex.EncodeToString函数)(可逆)

将字节数组转换为十六进制字符串
将其每个字节转换为两个十六进制字符,并将结果组合成一个字符串返回。但是比base64长
对比base64是十六进制编码可以直接参与运算,且方便查看二进制数据

哈希算法(不可逆)

哈希算法(Hash Function) 是一种将任意长度的数据转换为固定长度的输出,该输出基于输入数据,且唯一对应于输入数据。哈希函数是单向函数,它将输入转换为固定长度的输出,而且不可逆。

  • 常见的哈希算法:MD5、SHA-1、SHA-256、SHA-384、SHA-512

MD5(不可逆)

返回定长16字节的128位bit哈希值
数据完整性校验:MD5算法常用于验证数据的完整性。在数据传输过程中,发送方可以计算数据的MD5哈希值并将其发送给接收方。接收方收到数据后,再次计算哈希值并与发送方提供的哈希值进行比较。如果两者匹配,则说明数据在传输过程中没有被篡改。
密码存储:MD5算法也常用于密码存储。将用户密码通过MD5哈希后存储在数据库中,即使数据库被泄露,攻击者也无法直接获取用户的明文密码。然而,由于MD5算法存在已知的安全漏洞(如彩虹表攻击和碰撞攻击),现在已不推荐使用MD5来存储密码。更安全的做法是使用加盐哈希

func Test_MD5(t *testing.T) {
    salt := "123456"//盐值
	s := "hello"//需要哈希的字符串
	h := md5.New()//创建一个md5对象
	h.Write([]byte(s)+[]byte(salt))//写入需要哈希的字符串
	fmt.Println(h.Sum(nil))//Sum把哈希值追加到参数*[]byte中,并返回
}

即使加盐,MD5 仍然可以被破解。加盐只是增加了破解的难度,但并没有解决 MD5 本身的安全缺陷。以下是详细的解释:
加盐的作用和局限性
增加破解难度:加盐主要是为了防止彩虹表攻击(即预计算哈希值的查找表)。通过加入随机盐值,每个输入的哈希结果都会有所不同,即使输入相同也会生成不同的哈希值,这使得预计算哈希表变得无效。
防止简单暴力破解:如果每个输入都带有唯一的盐值,攻击者不能一次破解多个哈希值,他们必须针对每个盐值单独进行暴力破解。
盐值和输入:盐值并不需要保密,通常与哈希值一起存储。然而,盐值的存在不会消除哈希算法的固有弱点。如果哈希算法易于碰撞(如 MD5),攻击者仍然可以利用这些弱点进行攻击。

SHA-256(不可逆)

返回定长32字节的256bit哈希值
SHA-256 是一种哈希算法,属于安全哈希算法(Secure Hash Algorithm)家族的一员,用于将任意长度的输入数据转换为固定长度(256 比特,即 32 字节)的哈希值。SHA-256 具有以下特点:

  • 不可逆性:无法通过哈希值反推出原始数据。
  • 固定输出长度:不论输入数据的长度如何,SHA-256 始终生成长度为 256 位的哈希值。
  • 碰撞抗性:极难找到两个不同的输入数据生成相同的哈希值。
  • 广泛应用:用于数据完整性验证、数字签名、密码学安全等领域。
  • 在实际应用中,SHA-256 通常用于生成数据的唯一标识或验证数据在传输过程中是否被篡改。
func Test_SHA256(t *testing.T) {
	s := "hello"//需要哈希的字符串
	h := sha256.New()//创建一个sha256对象
	h.Write([]byte(s))//写入需要哈希的字符串
	fmt.Println(hex.EncodeToString(h.Sum(nil)))//Sum把哈希值追加到参数*[]byte中,并返回
}

MAC算法(不可逆)

HMAC 是一种基于哈希函数和密钥的消息认证码。它结合了哈希算法(如 SHA-256、SHA-1、MD5 等)和密钥,用于生成一种认证码,用于验证消息的完整性和真实性。HMAC 的特点包括:

  • 结合性:使用哈希函数和密钥生成认证码。
  • 安全性:提供对消息完整性的强保证,即使哈希函数被公开,只有知道密钥的人才能验证认证码。
  • 灵活性:可以选择不同的哈希算法,但常见选择是 SHA-256。
    HMAC使用SHA-256 + 密钥生成消息认证代码MAX(Message Authentication Code)(不可逆)
    HS256(HMAC with SHA-256)生成的 token 主要用于 验证消息的完整性和真实性 ,但它更常用于生成和验证身份认证的 token,例如 JSON Web Token (JWT)。
func Test_HMAC(t *testing.T) {
	key := []byte("secret")// 密钥
	a := hmac.New(sha256.New, key)// 创建一个新的hmac对象
	a.Write([]byte("hello"))// 写入需要签名的数据
	b := a.Sum(nil)// 计算签名并返回结果
	fmt.Println(base64.StdEncoding.EncodeToString(b))// 对结果进行Base64编码
	//iKqz7ejTrflNJquQ07r9SiCDBww7zOnAFO4EpEOEfAs=
}

加密算法(可逆)

加密算法(Encryption Algorithm) 是将明文(plaintext)转换为密文(ciphertext),或者将密文转换为明文的算法。
加密都是把一个block快加密成等长的密文,由于只能一个个块加密,要配合不同的加密模式例如下面的CBC模式和ECB模式,才能达到加密的目的。
对称加密比非对称加密快

对称加密算法(可逆)

  • 是指加密和解密使用相同密钥的加密算法。
  • 加密和解密速度快,安全性高。
  • 对称加密在开发中用的很多,如 AES,DES,3DES,RC。

DES(可逆)

  • 采用的密钥长度为 56 位
  • 加密后长度和输入相同
  • 安全性较低,目前不推荐使用

DES 加密算法的密钥长度应该是 8 个字节(64 位),不过实际上只有 56 位被用于加密计算,而 8 位用于奇偶校验,所以通常是使用 8 个字节的密钥
对于 DES 加密算法而言,数据长度必须是加密块大小的整数倍,即 8 字节。
但是近些年使用越来越少,因为 DES 使用56位密钥(密钥长度越长越安全),以现代计算能力24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用 DES 加密算法。

var key = []byte("12345678") // 56位密钥
//编码一个blocksize长度的块(8位)
func encoded(s []byte) []byte {
	block, _ := des.NewCipher(key) //Cipher是密码的意思
	ans := make([]byte, len(s))
	block.Encrypt(ans, s) //encrypt加密一个block块
	return ans
}
//解码一个blocksize长度的块(8位)
func decoded(s []byte) []byte {
	block, _ := des.NewCipher(key) //Cipher是密码的意思
	ans := make([]byte, len(s))
	block.Decrypt(ans, s) //decrypt解密一个block块
	return ans
}

AES(可逆)

  • 采用的密钥长度为 128 位、192 位或 256 位
  • 加密后长度和输入相同
  • 安全性高,目前推荐使用
func Test_AES(t *testing.T) {
	key := []byte("1234567890123456") // 16字节密钥
	plaintext := []byte("helloworldaaaaaa")// 16字节明文
	ans:=encoded_aes(key,plaintext)
	fmt.Println(ans)
	fmt.Println(deccode_aes(key,ans))
}
// 编码一个blocksize长度的块(16位)
func encoded_aes(keys,s []byte) []byte {
	block, _ := aes.NewCipher(keys) //Cipher是密码的意思
	ans := make([]byte, len(s))
	block.Encrypt(ans, s) //encrypt加密一个block块
	return ans
}
func deccode_aes(keys,s []byte) []byte {
	block, _ := aes.NewCipher(keys) //Cipher是密码的意思
	ans := make([]byte, len(s))
	block.Decrypt(ans, s) //encrypt加密一个block块
	return ans
}

区别

AES(Advanced Encryption Standard)和DES(Data Encryption Standard)是两种常见的对称加密算法,它们在多个方面有显著的区别:

  • AES:支持多种密钥长度,包括 AES-128、AES-192 和 AES-256,分别对应 128 位、192 位和 256 位密钥长度。这些密钥长度提供了不同级别的安全性,其中 AES-256 提供了最高级别的安全性。
  • DES:固定为 56 位的密钥长度,但实际上只有 56 位被用作加密密钥,其余 8 位用作奇偶校验,因此实际的加密强度是 56 位。由于密钥长度短,DES 的安全性在现代计算环境下已经不足以应对安全威胁。

非对称加密算法(可逆)

  • 是指加密和解密使用不同的密钥的加密算法。
  • 加密速度慢,安全性高。
  • 私钥加密,公钥解密
  • 非对称加密在开发中用的不多,如 RSA、DSA。

RSA(可逆)

  • 加密后数据长度 <= 密钥位数 / 8 - 11
  • 公钥和私钥在本质上是大整数。它们是基于大整数数学运算的加密系统的核心组成部分。在许多公钥加密算法(如 RSA、ECC)中,公钥和私钥都可以表示
    在 RSA 加密系统中:
    • 私钥由两个主要大整数组成:
      • n(模数):这是两个大素数 p 和 q 的乘积。
      • d(私有指数):这是一个与模数 n 相关的整数,用于解密。
    • 公钥由两个主要大整数组成:
      • n(模数):与私钥中的模数相同。
      • e(公有指数):这是一个通常选定的较小的整数,用于加密。
    • 这些整数在 RSA 密钥生成过程中通过数学运算生成并满足特定的数学关系,使得 RSA 加密和解密可以进行。
func Test_RSA(t *testing.T) {
	// 生成私钥和公钥
	privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
	publicKey := &privateKey.PublicKey
	// 保存私钥和公钥
	// res1 := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})
	// res2 := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: x509.MarshalPKCS1PublicKey(publicKey)})
	// ioutil.WriteFile("private.pem", res1, 0600)
	// ioutil.WriteFile("public.pem", res2, 0600)
	//读取私钥和公钥
	data, _ := ioutil.ReadFile("private.pem")
	block, _ := pem.Decode(data)
	privateKey, _ = x509.ParsePKCS1PrivateKey(block.Bytes)
	data, _ = ioutil.ReadFile("public.pem")
	block, _ = pem.Decode(data)
	publicKey, _ = x509.ParsePKCS1PublicKey(block.Bytes)

	// 加密
	src := []byte("hello world")
	encrypted, _ := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, src, nil)

	fmt.Println("加密后的数据:",base64.StdEncoding.EncodeToString(encrypted))

	// 解密
	decrypted, _ := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encrypted, nil)
	fmt.Println(string(decrypted))
}

ECC(可逆)

ECC 密钥
在椭圆曲线加密(ECC)中:

  • 私钥 是一个大整数 d,这是在某个范围内的随机数。
  • 公钥 是椭圆曲线上的一个点 Q,它是通过椭圆曲线上的基点 G 乘以私钥 d 得到的,即 Q = d * G。
  • 椭圆曲线加密依赖于椭圆曲线上的点运算,私钥和公钥在数学上有着密切的关系。

PEM格式存储密钥

pem.EncodeToMemory 是 Go 语言标准库中的一个函数,位于 encoding/pem 包内,用于将 PEM 编码的块(pem.Block)编码为字节切片并返回。
什么是 PEM 编码
PEM(Privacy-Enhanced Mail)编码是一种用于表示加密对象(如证书、私钥、公钥等)的标准。PEM 格式的文件通常以 -----BEGIN ----- 和 -----END ----- 包围数据块,并且数据块使用 Base64 编码。
例如:public.pem 文件的内容可能如下所示:

-----BEGIN PUBLIC KEY-----
MIIBCgKCAQEAvHxBCN85ydD+qwZvnIC1jt2X6PCivCgmgF0whfRfZE2CSukKJfWs
BZaPDdV8Zus/LPuH7PJs1rOazwQxyoewSy0hO2h66eAoyfCkGAwi30+lshop/oiK
BrHQW0g3S7Uywcfx+WQpFxP+YtWqXqhSGmb/Y83gYpvVtWUm5zzWleg1Iv1M2ihs
KBR+SxAoLRQmnycEmHlOorw138VR0wnH8Gmh9xNZ/+RV6wIOQVmf1VHu+dJnmf21
wAMdua9nOoibxrVz69IzjixiXi5M1El2jncAMGjRBJsMbwtfWPbABVju6f6PK13y
nYcf1rwlRcchxTeAwVnMCppMStrdhl2fTQIDAQAB
-----END PUBLIC KEY-----

pem.EncodeToMemory 的作用
pem.EncodeToMemory 的主要作用是将一个 pem.Block 对象编码为 PEM 格式的字节切片,方便存储或传输。
示例代码
下面是一个使用 pem.EncodeToMemory 的示例,它生成一个 RSA 私钥,并将其编码为 PEM 格式的字节切片,然后打印出来:

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
)

func main() {
	// 生成 RSA 私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		fmt.Println("Error generating RSA key:", err)
		return
	}

	// 将私钥转换为 PKCS#1 格式的 ASN.1 DER 编码
	privateKeyDER := x509.MarshalPKCS1PrivateKey(privateKey)

	// 创建一个 PEM Block
	privateKeyBlock := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: privateKeyDER,
	}

	// 将 PEM Block 编码为字节切片
	privateKeyPEM := pem.EncodeToMemory(privateKeyBlock)

	// 打印 PEM 编码的私钥
	fmt.Println(string(privateKeyPEM))
}

DER格式存储密钥

DER(Distinguished Encoding Rules)格式是一种二进制编码格式,用于存储 ASN.1 编码的结构。
DER 格式的文件通常以 0x30 开始,以 0x00 结束。
https://blog.csdn.net/fengshenyun/article/details/124596279

加密模式

CBC模式

  • 加密过程:
    对第一个数据块(明文)进行加密时,使用 IV 与明文进行异或运算,然后将结果再与加密算法的密钥进行加密,得到第一个密文块。
    对后续的数据块,将前一个密文块与当前的明文进行异或运算,然后再与密钥进行加密,得到当前的密文块。
    这样一直进行下去,每个密文块都依赖于前一个密文块的加密结果,因此形成了一条“链”。
  • 解密过程:
    解密过程与加密过程相反。首先使用 IV 与第一个密文块进行解密运算(使用解密算法和密钥),然后再与 IV 进行异或运算,得到第一个明文块。
    对后续的密文块,使用当前密文块与前一个密文块进行解密运算,然后再与前一个密文块进行异或运算,得到当前的明文块。
    这样依次进行下去,直至得到所有的明文块。
    AES-CBC demo
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}
func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	fmt.Println("unpadding:", origData[length-1])
	return origData[:(length - unpadding)]
 }
func Test_DES_CBC(t *testing.T) {
	key := []byte("12345678")                            // 8位密钥
	plaintext := []byte("hello woqrld for study des cbc") // 8字节明文
	iv := []byte("12345678")                             // 8字节iv
	block, _ := des.NewCipher(key)
	mode := cipher.NewCBCEncrypter(block, iv) // 创建一个新的CBC加密器
	fmt.Println("补位前明文:", plaintext, len(plaintext))
	plaintext = PKCS7Padding(plaintext, block.BlockSize()) // 填充
	fmt.Println("加密前明文:", plaintext, len(plaintext))
	ciphertext := make([]byte, len(plaintext))          // 16字节密文
	for i := 0; i < len(plaintext); i += des.BlockSize {
		blocks := plaintext[i : i+des.BlockSize] // 取出一个block块
		mode.CryptBlocks(ciphertext[i:], blocks) // 加密一个block块
	}
	fmt.Println("加密后密文:", ciphertext)

	
	fmt.Println("解密前密文:", ciphertext)
	block1, _ := des.NewCipher(key)
	mode1 := cipher.NewCBCDecrypter(block1, iv) // 创建一个新的CBC解密器
	plaintext1 := make([]byte, len(ciphertext))
	for i := 0; i < len(ciphertext); i += des.BlockSize {
		block2 := ciphertext[i : i+des.BlockSize] // 取出一个block块
		mode1.CryptBlocks(plaintext1[i:], block2) // 解密一个block块
	}
	fmt.Println("解密后明文:", plaintext1)
	plaintext1 = PKCS7UnPadding(plaintext1) // 去除填充
	fmt.Println("去除填充后明文:", string(plaintext1))
}

ECB模式

  • 加密过程:
    对每个数据块(明文)进行加密时,使用加密算法的密钥进行加密,得到当前的密文块。
  • 解密过程:
    对每个数据块(密文)进行解密时,使用加密算法的密钥进行解密,得到当前的明文块。

    ECB模式 demo
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}
func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	fmt.Println("unpadding:", origData[length-1])
	return origData[:(length - unpadding)]
}
func encrypt_DES_ECB(plaintext, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	//对明文进行填充
	plaintext = PKCS7Padding(plaintext, block.BlockSize())
	ciphertext := make([]byte, len(plaintext))
	//就是逐块EDS加密后拼接
	for bs, be := 0, block.BlockSize(); bs < len(plaintext); bs, be = bs+block.BlockSize(), be+block.BlockSize() {
		block.Encrypt(ciphertext[bs:be], plaintext[bs:be])
	}
	return ciphertext, nil
}
func decrypt_DES_ECB(ciphertext, key []byte) ([]byte, error) {
	block, _ := des.NewCipher(key)

	lens := len(ciphertext)
	ans := make([]byte, lens)
	//就是逐块EDS解密后拼接
	for bs, be := 0, block.BlockSize(); bs < len(ciphertext); bs, be = bs+block.BlockSize(), be+block.BlockSize() {
		block.Decrypt(ans[bs:be], ciphertext[bs:be])
	}
	//对密文进行去填充
	ans = PKCS7UnPadding(ans)
	return ans, nil
}
func Test_DES_ECB(t *testing.T) {
	// 加密
	key := []byte("12345678")
	src := []byte("hello world")
	ans, _ := encrypt_DES_ECB(src, key)
	fmt.Println(ans)
	// 解密
	ans1, _ := decrypt_DES_ECB(ans, key)
	fmt.Println(string(ans1))
}

标签:编码,加密,密钥,哈希,ans,非对称,byte,block
From: https://www.cnblogs.com/yuzhongrun/p/18248585

相关文章

  • 多项式与点值的双射 与 Reed–Solomon 编码纠错
    其实早就知道啊,不过apiot3之后还是在皮皮橙大神的指导下认真看了看.放一个$O(n^2)$的实现#include<bits/stdc++.h>usingu32=unsigned;usingi64=longlong;usingu64=unsignedlonglong;usingidt=std::size_t;constexpru32mod=998244353;constexpru32mul(u32......
  • 核心(Hutool-core)工具类(字符编码工具-CharsetUtil)
    介绍CharsetUtil主要针对编码操作做了工具化封装,同时提供了一些常用编码常量。常量常量在需要编码的地方直接引用,可以很好的提高便利性。字符串形式ISO_8859_1UTF_8GBKCharset对象形式CHARSET_ISO_8859_1CHARSET_UTF_8CHARSET_GBK方法编码字符串转为Charset对象Char......
  • openh264 帧内预测编码原理:WelsMdI4x4 函数
    介绍功能:针对4x4像素块的帧内模式决策原型:int32_tWelsMdI4x4(sWelsEncCtx*pEncCtx,SWelsMD*pWelsMd,SMB*pCurMb,SMbCache*pMbCache)参数:sWelsEncCtx*pEncCtx:指向编码上下文结构的指针,包含编码过程中需要的状态信息。SWelsMD*pWelsMd:指向运动检测结构的......
  • 【Go】用 Go 原生以及 Gorm 读取 SQLCipher 加密数据库
    本文档主要描述通过https://github.com/mutecomm/go-sqlcipher生成和读取SQLCipher加密数据库以及其中踩的一些坑用go去生成读取SQLCipher数据库用gorm去读取SQLCipher数据库在生成后分别用DBeaver、dbbrowser和sqlcipher读取SQLCipher数据库,基础操作见......
  • 机器学习归一化特征编码
    特征缩放因为对于大多数的机器学习算法和优化算法来说,将特征值缩放到相同区间可以使得获取性能更好的模型。就梯度下降算法而言,例如有两个不同的特征,第一个特征的取值范围为1——10,第二个特征的取值范围为1——10000。在梯度下降算法中,代价函数为最小平方误差函数,所以在使用......
  • 主流3D视频编码技术
    3D视频通过模拟人眼的立体视觉,使我们能够感受到深度和距离,提供了一种更加真实而富有沉浸感的视觉体验。长期以来,大量3D视频内容并没有使用专用的视频编码标准,而是使用通用的视频编码标准进行编码。主要的做法是将3D视频以SBS(sidebyside)的形式,把左右两个视点合并到一帧画面......
  • 非对称加密基于DH、DSA的的变种ECDH、ECDSA
    前面介绍DH、DSA都是基于离散对数的大数分解难题的。为什么有了还有ECC(椭圆曲线)呢,因为ECC需要的秘钥更短、更快(整数因子分解算法是最快的计算离散对数因子分解算法)椭圆曲线密码学简介(一):实数域的椭圆曲线及其群运算规则椭圆曲线公式曲线公式曲线没有奇异点,即处处光......
  • 短视频压缩与编码技术在短剧APP小程序开发中的应用:重要性分析
    在短剧APP小程序开发中,短视频的压缩与编码技术扮演着至关重要的角色。随着移动互联网的快速发展,用户对短视频内容的加载速度和播放质量提出了更高要求。本文将分析短视频压缩与编码技术对于短剧APP的重要性,并探讨其在实际开发中的应用。短视频压缩与编码技术的重要性提高加......
  • 短视频压缩与编码技术在短剧APP小程序开发中的应用:技术选择与工具推荐
    在短剧APP小程序开发中,选择合适的短视频压缩与编码技术及工具对于实现高效的视频处理至关重要。本文将探讨如何选择合适的技术和工具,以及推荐一些在实际开发中常用的解决方案。技术选择的原则平衡压缩率与视频质量:在选择压缩技术时,需要平衡压缩率与视频质量之间的关系。过......
  • 计算机组成原理历年考研真题对应知识点(数制与编码)
    目录2.1数制与编码2.1.1进位计数制及其相互转换【命题追踪——采用二进制编码的原因(2018)】【命题追踪——十进制小数转换为二进制小数(2021、2022)】2.1.2定点数的编码表示【命题追踪——补码的表示范围(2010、2013、2014、2022)】【命题追踪——补码和真值的相互转......