详谈前端中常用的加/密算法
本文主要详细介绍了在前端开发中常用的加/解密算法,以及前端如何实现。
总的来说:前端加密无论使用哪个加密都一样是有可能性被他人获取到相关的公钥或密钥的(比如:拦截请求、查看源代码等),然后进行加密与后端通讯,所以前端加密所谓的安全性是有限的,最主要的还是在后端!
一、加密算法
1、对称加密
含义: 加密和解密使用的是相同的秘钥,加密快而且方便,但缺点是密钥容易被偷或被破解。
常见算法: AES、DES、3DES 、RC2、RC4、RC5、RC6 、 Blowfish、国密SM4。
常见应用场景:
- 适用于需要高速加密/解密的场景,如:HTTP 传输的 SSL/TLS 部分。
- 适用于加密大量数据,如:文件加密、网络通信加密、数据加密、电子邮件、Web 聊天等。
2、非对称加密
含义: 加密和解密用的不是同一个秘钥,一般是用公钥加密,用私钥解密,公钥和私钥成对存在,公钥从私钥中提取产生公开给所有人。安全性要好于对称加密的,但性能就比较差。
常见算法: RSA、DSA、Elgamal、DSS、Merkle-Hellman背包算法、D-H、ECC(椭圆曲线加密算法)、国家商用密码SM2算法。
常见应用场景:
在实际应用中,非对称加密通常用于需要确保数据完整性和安全性的场合,如:数字证书的颁发、SSL/TLS 协议的加密、数字签名、加密小文件、密钥交换、实现安全的远程通信等。
3、单向散列函数
含义: 又称为消息摘要算法,是不可逆的加密算法,即对明文进行加密后,无法通过得到的密文还原回去得到明文。
常见的单项散列函数: MD5、SHA1、SHA256、SHA512 ,以及它们之前加上 Hmac(Keyed-hash message authentication codes) 后的 HmacMD5、HmacSHA1 等。
二、经典的加密算法
1、对称加密算法 —— AES(Advanced Encryption Standard)
英文全称为 Advanced Encryption Standard
,即高级加密标准的意思。
AES的推出,用于取代已经被证明不安全的 DES 算法。
AES 属于分组加密算法,因为它会把传入的明文数据以 128 bit 为一组分别处理。
其秘钥长度则可以是 128、192 和 256 bit。
AES 或者说对称加密算法的优点是速度快,缺点就是不安全,因为网站上的代码和秘钥都是明文,别人只要得到了加密结果再结合秘钥就能得到加密的数据了。
AES与DES
DES
优点:DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。
缺点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。
AES
优点:运算速度快,对内存的需求非常低,适合于受限环境。分组长度和密钥长度设计灵活, AES标准支持可变分组长度;具有很好的抵抗差分密码分析及线性密码分析的能力。
缺点:目前尚未存在对AES 算法完整版的成功攻击,但已经提出对其简化算法的攻击。
AES与DES之间的主要区别 在于加密过程:在DES中,将明文分为两半,然后再进行进一步处理;而在AES中,整个块不进行除法,整个块一起处理以生成密文。
相对而言,AES比DES快得多,与DES相比,AES能够在几秒钟内加密大型文件。
2、非对称加密—— RSA算法
RSA加密算法是一种非对称加密算法,使用"一对"密钥,分别是公钥和私钥,这个公钥和私钥其实就是一组数字,其二进制位长度可以是1024位或者2048位,长度越长其加密强度越大。
目前为止公之于众的能破解的最大长度为795位密钥,只要高于795位,相对就比较安全,所以目前为止这种加密算法一直被广泛使用。
由于RSA算法的原理都是大数计算,使得RSA最快的情况也比对称加密算法慢上好几倍。
RSA的速度是对应同样安全级别的对称加密算法的1/1000左右。
常见场景:
速度一直是RSA的缺陷,一般来说RSA只用于小数据的加密,比如对称加密算法的密钥,又或者数字签名。例如:在用户注册或登录的时候,用公钥对密码进行加密,再去传给后台,后台用私钥对加密的内容进行解密,然后进行密码校验或者保存到数据库。
3、单向散列函数 —— MD5(Message Digest Algorithm 5)
MD5 长度固定,不论输入的内容有多少字节,最终输出结果都为 128 bit,即 16 字节。
这就是为什么 MD5 以及其它单向散列函数是不可逆的 —— 输出定长代表会有数据丢失。
通常,我们可以用 16 进制字面值来表示它,每 4 bit 以 16 进制字面值显示,得到的是一个长度为 32 位的字符串。
注意,MD5 等单向散列函数具有高度的离散性,即:只要输入的明文不一样,得到的结果就完全不一样,哪怕是仅仅多了一个空格。
使用场景:
- 可以用来做密码的保护。比如可以不直接存储用户的密码,而是存储密码的 MD5 结果。但是现在一般认为用 MD5 来做加密是不太安全的,更多是利用 MD5 的高度离散性特点,用它来做数字签名、完整性校验,云盘秒传等;
- 数字签名。我们可以在发布程序时同时发布其 MD5,这样,别人下载程序后自己计算一遍 MD5,一对比就知道程序是否被篡改过,比如:植入了木马。
- 完整性校验。比如前端向后端传输一段非常大的数据,为了防止网络传输过程中丢失数据,可以在前端生成一段数据的 MD5 一同传给后端,这样后端接收完数据后再计算一次 MD5,就知道数据是否完整了。
MD5和SHA
-
MD5 :是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。
-
SHA(Secure Hash Algorithm) :可以对任意长度的数据运算生成一个固定位数的数值。
-
SHA/MD5对比:SHA在安全性方面优于MD5,并且可以选择多种不同的密钥长度。 但是,由于内存需求更高,运行速度可能会更慢。 不过,MD5因其速度而得到广泛使用,但是由于存在碰撞攻击风险,因此不再推荐使用。
三、前端常用的加/解方式
前端常用的方式有:crypto-js、encryptlong、jsencrypt、bcrypt
1、crypto-js
crypto-js支持多种算法:MD5、SHA1、SHA2、SHA3、RIPEMD-160
的哈希散列,以及进行 AES、DES、Rabbit、RC4、Triple DES
加解密。
crypto-js
对象如下:
1)常用加密方法
- 加密函数的参数:(明文字符串, 密钥字符串,可选参数对象),返回密文字符串。
- 加密函数:
Cryptojs.AES.encrypt
,Cryptojs.DES.encrypt
,Cryptojs.Rabbit.encrypt
,Cryptojs.RC4.encrypt
,Cryptojs.TripleDES.encrypt
2)常用解密方法
- 解密函数的参数:(密文字符串, 密钥字符串,可选参数对象),返回的结果必须用
.toString(CryptoJS.enc.Utf8)
转为明文。 - 解密函数是:
CryptoJS.AES.decrypt
,CryptoJS.DES.decrypt
,CryptoJS.Rabbit.decrypt
,CryptoJS.RC4.decrypt
,CryptoJS.TripleDES.decrypt
3)可选参数对象常用属性
mode
:加密模式
ECB (Electronic Codebook),将整个明文分成块,每个块独立加密。可能存在安全性问题。
CBC (Cipher Block Chaining),前一个块的密文作为下一个块的加密向量,提高了安全性。
CFB (Cipher Feedback),前一个密文块作为密钥加密当前明文块,可按比块更小单位加密。
OFB (Output Feedback),使用函数产生的密钥流进行异或运算,提供加密流。
CTR (Counter),使用计数器的值加密,并与明文进行异或运算,提供加密效果。
CTRGladman,CTRGladman 模式paddig
:填充方式
AnsiX923,在数据末尾填充零字节,最后一个字节表示需要填充的字节数。
Iso10126,在数据末尾填充随机字节,最后一个字节表示需要填充的字节数。
Iso97971,使用 ISO/IEC 9797-1 填充方案,在数据末尾填充\x80
加上零或多个\x00
直到块的大小。
NoPadding,不进行任何填充,要求数据长度必须是块大小的整数倍。
Pkcs7,使用 PKCS#7填充方案,在数据末尾填充字节,字节的值表示需要填充的字节数。
ZeroPadding,在数据末尾填充零字节,直到数据长度满足块大小的整数倍。vi
: 偏移向量formatter
:自定义格式enc
: 指定字符编码模式,包含8 个 API:“Hex”, “Latin1”, “Utf8”, “Utf16BE”, “Utf16”, “Utf16LE”, “Base64”, “Base64url”algo
:包含很多算法- 哈希算法
MD5 (常用),生成 128 位哈希值,用于校验数据完整性
SHA1 (常用系列),生成 160 位哈希值
SHA256,生成 256 位哈希值
SHA224,生成 224 位哈希值
SHA512,生成 512 位哈希值
SHA384,生成 384 位哈希值
SHA3,SHA-3 哈希算法
RIPEMD160,另一种生成 160 位哈希值的算法
HMAC,基于密钥的哈希消息认证码
PBKDF2,密码基于密钥派生函数
EvpKDF,另一种密钥派生函数 - 对称加密算法
AES (常用),高级加密标准,用于对称加密和解密数据
DES ,数据加密标准,较早的对称加密算法
TripleDES ,对 DES 进行多次加密以增加安全性 - 流式加密算法
RC4 ,流式加密算法
RC4Drop,RC4 的变种
Rabbit ,另一种流式加密算法
RabbitLegacy,Rabbit 算法的旧版本 - 其他
Blowfish,对称加密算法,用于加密和解密数据
- 哈希算法
2、jsencrypt
jsencrypt是一个基于rsa加解密的js库。
new jsencrypt()
如下:
jsencrypt 的加解密过程需要用到 OpenSSL 来生成秘钥,OpenSSL 是一个开源的软件,它是对 SSL 协议的实现。
RSA秘钥生成方式
- a. 利用工具,在线网站:http://tools.jb51.net/password/rsa_encode
- b. Mac系统内置OpenSSL(开源加密库),所以可以直接在终端上使用命令。
命令 | 含义 |
---|---|
genrsa | 生成并输入一个RSA私钥 |
rsautl | 使用RSA密钥进行加密、解密、签名和验证等运算 |
rsa | 处理RSA密钥的格式转换等问题 |
具体操作:
openssl genrsa -out private.pem 1024 // 生成私钥,密钥长度为1024bit
openssl rsa -in private.pem -pubout -out public.pem // 从私钥中提取公钥,同时会生成了private.pem 和 public.pem两个文件
cat private.pem // 查看私钥
cat public.pem // 查看公钥
jsencrypt使用注意点
jsencrypt加密的对象一定要是字符串,jsencrypt加密长对象或者数据太多,可能会返回false
,或者报错:Message too long for RSA
。
可能导致问题的原因:
- openssl生成的密匙可能会有格式问题,需要转化一下格式PKCS#1和PKCS#8
- jsencrypt的加密长度有限制,它只能支持100多位的加密,当字符串太长会返回false
解决办法:用encryptlong
3、encryptlong
encryptlong是基于 jsencrypt 扩展了长文本分段加解密功能,即:需要进行rsa加密的内容比较长时,就用encryptlong进行实现。
new encryptlong()
如下:
4、bcryptjs
bcrypt是一种用于密码哈希的加密算法,它是基于Blowfish算法的加强版,生成的密文为60位。
bcrypt是一种加盐的单向Hash,不可逆的加密算法,同一种明文,每次加密后的密文都不一样,而且不可反向破解生成明文,破解难度很大。
bcryptjs
对象如下:
应用场景:
- 用户注册:当用户注册时,需要将其密码进行哈希处理后再存储到数据库中。
- 用户登录:当用户登录时,需要将其输入的密码与存储在数据库中的哈希值进行比较,从而得知密码是否正确。
- 密码重置:当用户忘记密码时,可以使用Bcrypt算法生成一个新的哈希值,用于重置密码。
bcrypt原理:
bcrypt算法是一种密码哈希函数,它采用了salt和cost两种机制来增强密码的安全性。
- salt:为了防止彩虹表攻击,bcrypt算法会生成一个随机salt值,将salt与密码拼接后再进行哈希运算。这个salt值是由22个可打印字符组成的字符串,它的作用是使得相同密码的哈希值在不同的salt值下产生不同的结果,从而增加密码破解的难度。
- cost:bcrypt算法会将明文密码和salt进行多次迭代的哈希运算。迭代的次数是由cost值决定的,cost值越大,运算次数越多,从而增加密码破解的难度。通常来说,建议将cost值设置为12,这样可以保证安全性和性能的平衡。
bcrypt加密后值说明
bcrypt 密码强度一般在10-12。默认是10,太强会导致速度变慢。
加密得到的字符串的格式:$2a $[cost] $[22 character salt] [31 character hash]
cost
:是代价因子,这里的10 表示是2的10次方,也就是1024轮22 character salt
:16个字节(128bits)的salt经过base64编码得到的22长度的字符31 character hash
:24个字节(192bits)的hash,经过bash64的编码得到的31长度的字符
如:
四、具体实现示例
通过npm安装: npm install crypto-js encryptlong jsencrypt bcrypt
1、crypto-js实现RSA加/解密
import CryptoJS from "crypto-js";const encryptByRSA = (content, publicKey) => {const rsa = new JSEncrypt();rsa.setPublicKey(publicKey);return rsa.encrypt(content);
};const decryptFromRSA = (content, privateKey) => {const rsa = new JSEncrypt();rsa.setPrivateKey(privateKey);return rsa.decrypt(content);
};
2、crypto-js实现AES加/解密
import CryptoJS from "crypto-js";const encryptByAES = (content, key, iv) => {try {if (typeof content === "object") {content = JSON.stringify(content);}const data = CryptoJS.enc.Utf8.parse(data);const aes = CryptoJS.AES.encrypt(data, key, {mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,iv: CryptoJS.enc.Utf8.parse(iv)});return aes.ciphertext.toString();} catch (e) {return content;}
};const decryptFromAES = (content, key, iv) => {try {const encryptedHexStr = CryptoJS.enc.Hex.parse(content);const data = CryptoJS.enc.Base64.stringify(encryptedHexStr);const aes = CryptoJS.AES.decrypt(data, key, {mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,iv: CryptoJS.enc.Utf8.parse(iv)});const originalText = aes.toString(CryptoJS.enc.Utf8);return originalText.toString();} catch (e) {return content;}
};
3、jsencrypt进行RSA加/解密
import JSEncrypt from "jsencrypt";// 注:如果是对象/数组的话,需要先JSON.stringify转换成字符串
const encryptByRSA = (content, publicKey) => {const rsa = new JSEncrypt();rsa.setPublicKey(publicKey);return rsa.encrypt(content);
};const decryptFromRSA = (content, privateKey) => {const rsa = new JSEncrypt();rsa.setPrivateKey(privateKey);return rsa.decrypt(content);
};
4、encryptlong进行RSA加/解密
import JSEncryptLong from "encryptlong";// 注:如果是对象/数组的话,需要先JSON.stringify转换成字符串
const encryptLongByRSA = (content, publicKey) => {const rsa = new JSEncryptLong();rsa.setPublicKey(publicKey);return rsa.encryptLong(content);
};const decryptLongFromRSA = (content, privateKey) => {const rsa = new JSEncryptLong();rsa.setPrivateKey(privateKey);return rsa.decryptLong(content);
};
测试示例:
const PUBLIC_KEY = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKX1Fs2JUD25zrAEwPnjnZC0azrl1XjGzGrJ64eb1lr9QVVOO2zGKZdqDLZD4Ut4Mp6GHMaqqFXKm+zN7IAXu+mqZbUrqUziHE5YGC02wObiZEzfa6V9a8ZvqpB+Z8KO+hAkkjzjMl+E+hDORpZmez3SMzetn7mcCeLw8/vmxz3QIDAQAB`;const PRIVATE_KEY = `MIICXgIBAAKBgQDKX1Fs2JUD25zrAEwPnjnZC0azrl1XjGzGrJ64eb1lr9QVVOO2zGKZdqDLZD4Ut4Mp6GHMaqqFXKm+zN7IAXu+mqZbUrqUziHE5YGC02wObiZEzfa6V9a8ZvqpB+Z8KO+hAkkjzjMl+E+hDORpZmez3SMzetn7mcCeLw8/vmxz3QIDAQABAoGBAJBr6b4V6nJwXdHPyngy4PGl/HTqcK60BkTamALqzmEtU9tNU5z2yz7dy+6awTsjo7Vao8CwNrUp5fHGXw65EEc1/3Iu2Fiix0XF7RP4NFSoxbBmzQW1nUK/5DFi4VR1uhEmdbgLwGabsdqzeUqhRKkRGAPVCotBjaDBOu0J3Mu5AkEA+SM7Ctu7evOvZwjWrp9a5MGxJ9yLLabbIuWL+420jr2G6ojaTZ2ROA2DWWQPx4JqWxDHttomrb38dk2emP2WAwJBAM/yU58YRQ+dTeuTzNYC1JdWcs35n9+hoVP7y+x29CmcqDTPp3nRBbbq88yMb2nZdlwthWi7BurNHsRJFqj0GJ8CQF5gJCuW1UxcJ2PGi1yW7R2e6fcJqoden8B2aDKgmXdBAGyz7s5cE/jB1bH1H60aECPzFVSFCwXh5FMEUEHwPfUCQQC7JqZ57lbhebrSRcA58GwzFFvY40wu8gIHWvwqgti2xsZgWW+qZCPXf9gSBWaUhmJPDa0fGAxesGN7VyhswNuTAkEAzCFNqL/zwHXcwh9YyHTdk/bRWIJq49jTA+vbgGv0szKIvGRKoRbub3NEUiI80TDsCAvbJ6R80J7RjnpmShOwcA==`;const constent = {phone: "8000000001",firstName: "vickie",id: "1234XXXX4567",data: {timestamp: 1572321851823,inter1: ["123123123", "123123123", "123123123", "123123123", "123123123"],inter2: ["123123123", "123123123", "123123123", "123123123", "123123123"],inter3: ["123123123", "123123123", "123123123", "123123123", "123123123"],inter4: ["123123123", "123123123", "123123123", "123123123", "123123123"],inter5: ["123123123", "123123123", "123123123", "123123123", "123123123"],inter6: ["123123123", "123123123", "123123123", "123123123", "123123123"],stream: {},caton: {},card: []}
};
const encryptResult = encryptLongByRSA(JSON.stringify(constent), PUBLIC_KEY);
const decryptResult = decryptLongFromRSA(encryptResult, PRIVATE_KEY);
5、bcrypt进行哈希加密
import bcrypt from 'bcryptjs';// 同步实现hash加密:每一次生成的hash都会不一样, cost数字越大,哈希值就越安全,但性能会差一点
const encryptHash = (plaintextPassword, cost) => {const salt = bcrypt.genSaltSync(cost);const hash = bcrypt.hashSync(plaintextPassword, salt);return hash;
};// 同步验证
const isPass = (plaintextPassword, hash) => {return bcrypt.compareSync(plaintextPassword, hash);
};// 测试
const passwordHash = encryptHash("test", 10);
console.log(passwordHash, isPass("test", passwordHash)); // 生成的不可逆密文 true
相关文章:
详谈前端中常用的加/密算法
本文主要详细介绍了在前端开发中常用的加/解密算法,以及前端如何实现。 总的来说:前端加密无论使用哪个加密都一样是有可能性被他人获取到相关的公钥或密钥的(比如:拦截请求、查看源代码等),然后进行加密与…...
宣布全面推出适用于 macOS 的 Amazon EC2 M2 Pro Mac 实例
即日起,Amazon Elastic Compute Cloud (Amazon EC2) M2 Pro Mac 实例现已全面推出 (GA)。在为 Apple 平台(例如 iOS、macOS、iPadOS、tvOS、watchOS、visionOS 和 Safari)构建和测试应用程序时,这些实例的性能比现有的 M1 Mac 实例…...
【记录版】SpringBoot下Filter注册源码解读
SpringBoot TomcatEmbeddedContext Servlet ApplicationFilterChain Filter 背景: 在之前博客中有说明SpringBoot内嵌Web容器后,Filter及Servlet解析与注册流程的变化。将Filter实例封装成FilterRegistrationBean实例并添加到ServletContext后&…...
WPF的WebBrowser控件
在 WPF 中显示网页,你可以使用 WebBrowser 控件来实现。WebBrowser 控件是一个嵌入式的浏览器控件,可以加载和显示网页内容。 以下是在 WPF 中显示网页的示例代码: <Window x:Class"WpfApp.MainWindow"xmlns"http://sche…...
WX小程序案例(一):弹幕列表
WXML内容 <!--pages/formCase/formCase.wxml--> <!-- <text>pages/formCase/formCase.wxml</text> --> <view class"bk bkimg"><!-- <image src"/static/imgs/ceeb653ely1g9na2k0k6ug206o06oaa8.gif" mode"scal…...
基于ssm医用物理学实验考核系统论文
摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本医用物理学实验考核系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数…...
鸿蒙HarmonyOS4.0 入门与实战
一、开发准备: 熟悉鸿蒙官网安装DevEco Studio熟悉鸿蒙官网 HarmonyOS应用开发官网 - 华为HarmonyOS打造全场景新服务 应用设计相关资源: 开发相关资源: 例如开发工具 DevEco Studio 的下载 应用发布: 开发文档:...
论文阅读——GroupViT
GroupViT: Semantic Segmentation Emerges from Text Supervision 一、思想 把Transformer层分为多个组阶段grouping stages,每个stage通过自注意力机制学习一组tokens,然后使用学习到的组tokens通过分组模块Grouping Block融合相似的图片tokens。通过这…...
时光机器:用rrweb打造可回溯的用户体验!
在现代Web应用中,理解用户如何与你的产品互动变得越来越重要。rrweb(record and replay the web)是一个开源库,它能够记录用户在网站上的所有操作,并能够像回放视频一样回放这些操作。这就像给你的网站装上了一台时光机…...
不同的葡萄品种的葡萄酒有什么共同特质?
在某种程度上几乎所有的葡萄酒都是混合的,在大多数葡萄酒产地,法律允许在单一品种葡萄酒中混入高达15%的另一种葡萄酒,且还能被称为由主要葡萄酿造的单一品种葡萄酒酒。这些单一品种葡萄酒混合了少量其他葡萄酒,是为了创造一个特质…...
Visual Studio编辑器中C4996 ‘scanf‘: This function or variable may be unsafe.问题解决方案
目录 编辑 题目:简单的ab 1. 题目描述 2. 输入格式 3. 输出格式 4. 样例输入 5. 样例输出 6. 解题思路 7. 代码示例 8. 报错解决 方案一 方案二 方案三 方案四 总结 题目:简单的ab 1. 题目描述 输入两个整数a和b,…...
C与C++编程语言的区别和联系
一、引言 C和C是两种广泛使用的编程语言,它们都在软件开发领域有着广泛的应用。虽然C是从C语言演化而来的,但两者之间存在一些重要的区别和联系。本文将详细介绍这两种编程语言的相同点和不同点,并通过实际例子进行说明。 二、C与C的相同点 …...
UE4 UMG 颜色字体和PS对应关系
与PS中对应的是Hex sRGB色号 但是PS中采用的16进制色号为6位 UE4中的为8位 UMG制作时默认dpi为96像素/英寸,psd默认dpi是72像素/英寸。 在GUI设计时将dpi设为96,或者将72dpi下字体的字号乘以0.75,都能还原效果图中的效果。...
EasyExcel处理表头的缓存设置
在学习EasyExcel 时会发现针对使用类模型配置表头相关属性时,EasyExcel 会使用到缓存技术以提升表头的解析速度如下代码: 这些参数再何时设置的哪? 在easyExcel 基础参数设置中会有这个参数filedCacheLocation 。默认采用的使用线程级别的…...
数据挖掘任务一般流程
数据挖掘是从大量数据中提取有价值信息的过程。它涉及多个步骤,每一步都对整个数据挖掘过程至关重要。以下是数据挖掘任务的一般流程: 业务理解: 确定业务目标。评估当前情况。定义数据挖掘问题。制定一个初步计划来达到这些目标。 数据理…...
人工智能计算机视觉:解析现状与未来趋势
导言 随着人工智能的迅速发展,计算机视觉技术逐渐成为引领创新的关键领域。本文将深入探讨人工智能在计算机视觉方面的最新进展、关键挑战以及未来可能的趋势。 1. 简介 计算机视觉是人工智能的一个重要分支,其目标是使机器具备类似于人类视觉的能力。这…...
5.1 C++11强类型枚举
一、C枚举的缺陷 1.类型冲突 枚举值和类型都是全局可见的, 与正常C的namespace、类等都是格格不入的,并且还容易导致冲突。 enum Type { General, Light, Medium, Heavy }; enum Category { General, Pistol, MachineGun, Cannon }; 如果在相同作用域…...
Android : BottomNavigation底部导航_简单应用
示例图: 1.先创建底部导航需要的图片 res → New → Vector Asset 创建三个矢量图 图片1 baseline_home.xml <vector android:height"24dp" android:tint"#000000"android:viewportHeight"24" android:viewportWidth"24…...
基于ssm培训学校教学管理平台论文
摘 要 社会的进步,教育行业发展迅速,人们对教育越来越重视,在当今网络普及的情况下,教学管理模式也开始逐渐网络化,学校开始网络教学管理模式。 本文研究的培训学校教学管理平台基于SSM框架,采用Java技术和…...
关于嵌入式开发的一些信息汇总:C标准、芯片架构、编译器、MISRA-C
关于嵌入式开发的一些信息汇总:C标准、芯片架构、编译器、MISRA-C 关于C标准芯片架构是什么?架构对芯片有什么作用?arm架构X86架构mips架构小结 编译器LLVM是什么?前端在干什么?后端在干什么? MISRA C的诞生…...
java实现局域网内视频投屏播放(二)爬虫
代码链接 视频播放原理 大多视频网站使用的是m3u8,m3u8其实不是一个真正的视频文件,而是一个视频播放列表(playlist)。它是一种文本文件,里面记录了一系列的视频片段(segment)的网络地址。这些…...
a标签的target属性
<a> 标签的 target 属性规定在何处打开链接文档。 最常用的两个值是: _self : 在当前窗口打开被链接文档 _blank:在新窗口打开被链接文档 就是常见浏览网页打开链接的方式...
无mac在线申请hbuilderx打包ios证书的方法
hbuilderx是一个跨平台的开发工具,可以开发android和ios的app应用。打包hbuilderx应用需要hbuilderx打包证书。但是很多使用hbuilderx开发的程序员,并没有mac电脑,而申请ios的证书,hbuilderx官网的教程却是需要mac电脑的ÿ…...
[css] flex wrap 九宫格布局
<div class"box"><ul class"box-inner"><li>九宫格1</li><li>九宫格2</li><li>九宫格3</li><li>九宫格4</li><li>九宫格5</li><li>九宫格6</li><li>九宫格7&l…...
云上丝绸之路| 云轴科技ZStack成功实践精选(西北)
古有“丝绸之路” 今有丝绸之路经济带 丝路焕发新生,数智助力经济 云轴科技ZStack用“云”护航千行百业 沿丝绸之路,领略西北数字化。 古丝绸之路起点-陕西 集历史与现代交融,不仅拥有悠久的历史文化积淀,而且现代化、数字化发…...
Java8 IfPresent 与 forEach 的组合操作
一、需求背景 Java8的Optional接口是我们经常使用的一个接口,尤其是对对象进行判空的时候,需要经常使用到IfPresent()。 但是,如果是对List进行判空、循环的话,就稍显繁杂了,因为几乎每次对List进行操作的时候&a…...
WebGL+Three.js入门与实战——给画布换颜色、绘制一个点、三维坐标系
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
SystemServer 进程启动过程
首语 SystemServer进程主要用于启动系统服务,诸如AMS、WMS、PMS都是由它来创建的。在系统的名称为"system_server",Android核心服务都是它启动,它是非常重要。 Zygote处理SystemServer进程 在 Zygote启动过程 文章中分析我们知道…...
Java EE 多线程之 JUC
文章目录 1. Callable 接口2. ReentrantLock3. 信号量4. CountDownLatch JUC这里就是指(java.util.concurrent) concurrent 就是并发的意思 这个包里的内容,主要就是一些多线程相关的组件 1. Callable 接口 Callable 也是一种创建线程的方式…...
Unity光照模型实践
光照作为3D渲染中最重要的部分之一,如何去模拟真实环境的光照是重要的研究内容,但是现实环境光照过于复杂,有很多经典好用的光照模型去近似真实光照。 根据基础的Phong模型 最终某个点的结果为 环境光Ambient 漫反射光Diffuse 高光Specula…...
徐州网站开发怎样/网络营销课程学什么
最近总有童鞋问,拿到的测序数据,我怎么知道或者评判质量好坏呢,别着急,今天给你推荐一款软件,让你轻松知道数据质量情况,它就是FastQC,它是高通量测序数据的高级质控工具,输入FastQ&…...
如何查看网站域名信息/福州seo网站排名
去年,滴滴顺风车连续发生两起恶性事件,随后,滴滴顺风车于2018年8月27日宣布无限期下线整改。时隔400多天后,滴滴顺风车今天再次上线,在哈尔滨、太原、江苏常州3个城市上线试运营。顺风车在安全方面有哪些新的措施&…...
怎么搭建自己的博客网站/网络销售哪个平台最好
大家好,我是煎鱼。一年半前分享了《先睹为快,Go2 Error 的挣扎之路》的文章,内容涉及 Go1 错误处理的问题、Go1.13 的加强、Go2 的新错误处理提案的详解。有多少小伙伴还记得 Go2 的新错误提案的 “美好” 未来?当时 Go2 的新提案…...
泛微 企业网站建设计划/sns营销
欢迎喜欢实施运维及数据的小伙伴加入群进行谈论! 运维技术群:263859509 lvs 原理 LVS通过工作于内核的ipvs模块来实现功能,其主要工作于netfilter 的INPUT链上。 而用户需要对ipvs进行操作配置则需要使用ipvsadm这个工具。 ipvsadm主要用于设…...
购物类网站开发/百度推广售后
上周的帖子专门针对OOP 。 尽管有普遍的看法,但该练习并未使用访问器( 即获取器和设置器)或共享的可变状态来解决。 该解决方案的实现基于Kotlin语言提供的传统OOP构造:类,继承和重写。 其他语言可能会提供不同的OOP方…...
专门做玉的网站/seo的概念是什么
微服务技术栈选型,看了这个别的可以不用看了 摘要: 本文由PPmoney架构师敖小剑分享:微服务的核心技术,目前可选的开源微服务框架,以及为微服务提供支撑的基础设施。 前言 大家好,我是敖小剑,…...