总结
为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。
内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。
包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。
前端面试题汇总
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
JavaScript
性能
linux
k[2] = MK[2] ^ FK[2]
k[3] = MK[3] ^ FK[3]
for (var i = 0; i < 32; i++) {
k[i + 4] = k[i] ^ this.sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i])
SK[i] = k[i + 4]
}
}
this.padding = function (input, mode) {
if (input == null) {
return null
}
var ret = null
if (mode == this.SM4_ENCRYPT) {
var p = parseInt(16 - (input.length % 16))
ret = input.slice(0)
for (var i = 0; i < p; i++) {
ret[input.length + i] = p
}
} else {
var p = input[input.length - 1]
ret = input.slice(0, input.length - p)
}
return ret
}
this.sm4_one_round = function (sk, input, output) {
var i = 0
var ulbuf = new Array(36)
ulbuf[0] = this.GET_ULONG_BE(input, 0)
ulbuf[1] = this.GET_ULONG_BE(input, 4)
ulbuf[2] = this.GET_ULONG_BE(input, 8)
ulbuf[3] = this.GET_ULONG_BE(input, 12)
while (i < 32) {
ulbuf[i + 4] = this.sm4F(ulbuf[i], ulbuf[i + 1], ulbuf[i + 2], ulbuf[i + 3], sk[i])
i++
}
this.PUT_ULONG_BE(ulbuf[35], output, 0)
this.PUT_ULONG_BE(ulbuf[34], output, 4)
this.PUT_ULONG_BE(ulbuf[33], output, 8)
this.PUT_ULONG_BE(ulbuf[32], output, 12)
}
this.sm4_crypt_ecb = function (ctx, input) {
if (input == null) {
alert(‘input is null!’)
}
if (ctx.isPadding && ctx.mode == this.SM4_ENCRYPT) {
input = this.padding(input, this.SM4_ENCRYPT)
}
var i = 0
var length = input.length
var bous = new Array()
for (; length > 0; length -= 16) {
var out = new Array(16)
var ins = input.slice(i \* 16, 16 \* (i + 1))
this.sm4\_one\_round(ctx.sk, ins, out)
bous = bous.concat(out)
i++
}
var output = bous
if (ctx.isPadding && ctx.mode == this.SM4\_DECRYPT) {
output = this.padding(output, this.SM4\_DECRYPT)
}
for (var i = 0; i < output.length; i++) {
if (output[i] < 0) {
output[i] = output[i] + 256
}
}
return output
}
this.sm4_crypt_cbc = function (ctx, iv, input) {
if (iv == null || iv.length != 16) {
alert(‘iv error!’)
}
if (input == null) {
alert('input is null!')
}
if (ctx.isPadding && ctx.mode == this.SM4\_ENCRYPT) {
input = this.padding(input, this.SM4\_ENCRYPT)
}
var i = 0
var length = input.length
var bous = new Array()
if (ctx.mode == this.SM4\_ENCRYPT) {
var k = 0
for (; length > 0; length -= 16) {
var out = new Array(16)
var out1 = new Array(16)
var ins = input.slice(k \* 16, 16 \* (k + 1))
for (i = 0; i < 16; i++) {
out[i] = ins[i] ^ iv[i]
}
this.sm4\_one\_round(ctx.sk, out, out1)
iv = out1.slice(0, 16)
bous = bous.concat(out1)
k++
}
} else {
var temp = []
var k = 0
for (; length > 0; length -= 16) {
var out = new Array(16)
var out1 = new Array(16)
var ins = input.slice(k \* 16, 16 \* (k + 1))
temp = ins.slice(0, 16)
sm4\_one\_round(ctx.sk, ins, out)
for (i = 0; i < 16; i++) {
out1[i] = out[i] ^ iv[i]
}
iv = temp.slice(0, 16)
bous = bous.concat(out1)
k++
}
}
var output = bous
if (ctx.isPadding && ctx.mode == this.SM4\_DECRYPT) {
output = this.padding(output, this.SM4\_DECRYPT)
}
for (var i = 0; i < output.length; i++) {
if (output[i] < 0) {
output[i] = output[i] + 256
}
}
return output
}
}
// function SM4Util(key = ‘1111111111111111’) {
function SM4Util() {
console.log(‘SM4Util key----’, key)
// 和后端key一致(key为密钥)
// this.secretKey = key
this.secretKey = ‘1111111111111111’
// 当时用CBC模式的时候
this.iv = ‘1111111111111111’
this.hexString = false
// ECB模式加密
this.encryptData_ECB = function (plainText) {
try {
var sm4 = new SM4()
var ctx = new SM4_Context()
ctx.isPadding = true
ctx.mode = sm4.SM4_ENCRYPT
var keyBytes = stringToByte(this.secretKey)
sm4.sm4_setkey_enc(ctx, keyBytes)
var encrypted = sm4.sm4_crypt_ecb(ctx, stringToByte(plainText))
var cipherText = base64js.fromByteArray(encrypted)
if (cipherText != null && cipherText.trim().length > 0) {
cipherText.replace(/(\s*|\t|\r|\n)/g, ‘’)
}
return cipherText
} catch (e) {
console.error(e)
return null
}
}
// CBC模式加密
this.encryptData_CBC = function (plainText) {
try {
var sm4 = new SM4()
var ctx = new SM4_Context()
ctx.isPadding = true
ctx.mode = sm4.SM4_ENCRYPT
var keyBytes = stringToByte(this.secretKey)
var ivBytes = stringToByte(this.iv)
sm4.sm4\_setkey\_enc(ctx, keyBytes)
var encrypted = sm4.sm4\_crypt\_cbc(ctx, ivBytes, stringToByte(plainText))
var cipherText = base64js.fromByteArray(encrypted)
if (cipherText != null && cipherText.trim().length > 0) {
cipherText.replace(/(\s\*|\t|\r|\n)/g, '')
}
return cipherText
} catch (e) {
console.error(e)
return null
}
}
stringToByte = function (str) {
var bytes = new Array()
var len, c
len = str.length
for (var i = 0; i < len; i++) {
c = str.charCodeAt(i)
if (c >= 0x010000 && c <= 0x10ffff) {
bytes.push(((c >> 18) & 0x07) | 0xf0)
bytes.push(((c >> 12) & 0x3f) | 0x80)
bytes.push(((c >> 6) & 0x3f) | 0x80)
bytes.push((c & 0x3f) | 0x80)
} else if (c >= 0x000800 && c <= 0x00ffff) {
bytes.push(((c >> 12) & 0x0f) | 0xe0)
bytes.push(((c >> 6) & 0x3f) | 0x80)
bytes.push((c & 0x3f) | 0x80)
} else if (c >= 0x000080 && c <= 0x0007ff) {
bytes.push(((c >> 6) & 0x1f) | 0xc0)
bytes.push((c & 0x3f) | 0x80)
} else {
bytes.push(c & 0xff)
}
}
console.log(‘bytes----’, bytes)
return bytes
}
byteToString = function (arr) {
if (typeof arr === ‘string’) {
return arr
}
var str = ‘’,
_arr = arr
for (var i = 0; i < _arr.length; i++) {
var one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/)
if (v && one.length == 8) {
var bytesLength = v[0].length
var store = _arr[i].toString(2).slice(7 - bytesLength)
for (var st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2)
}
str += String.fromCharCode(parseInt(store, 2))
i += bytesLength - 1
} else {
str += String.fromCharCode(_arr[i])
}
}
return str
}
}
### 2. body 标签上引入该文件
### 3. 使用 - ECB 模式加密
// 加密 - 使用默认秘钥 1111111111111111
var sm4 = new SM4Util();
sm4.encryptData_ECB(‘123’);
// 加密 - 使用自定义秘钥 93F3044B07393417A737E2CC389D01AF (需将 sm4.js 文件中SM4Util 函数处注释的代码打开)
var sm4 = new SM4Util(‘93F3044B07393417A737E2CC389D01AF’);
sm4.encryptData_ECB(‘123’); // 后端解密的好像对不上,
该加密办法参考博客 <https://blog.youkuaiyun.com/wzk_blog/article/details/122668114>
## 【方法3】
### 1. 本地写 js 文件
`@/utils/SM4Util/index.js`
let base64js = require(‘./base64js’)
let Hex = require(‘./hex’)
let SM4 = require(‘./sm4’)
function SM4Util() {}
/**
* sm4 ecb 加密
* @param utf8Str
* @param utf8Key
*/
SM4Util.sm4ECBEncrypt = function (utf8Str, utf8Key) {
if (!utf8Key) {
utf8Key = ‘zzfh!@#$QazxWsxc’
}
let sm4 = new SM4()
let keyBytes = Hex.utf8StrToBytes(utf8Key)
let contentBytes = Hex.utf8StrToBytes(utf8Str)
let cipher = sm4.encrypt_ecb(keyBytes, contentBytes)
return base64js.fromByteArray(cipher)
}
/**
* sm4 ecb 解密
* @param utf8Str
* @param utf8Key
*/
SM4Util.sm4ECBDecrypt = function (base64Str, utf8Key) {
if (!utf8Key) {
utf8Key = ‘zzfh!@#$QazxWsxc’
}
let sm4 = new SM4()
let keyBytes = Hex.utf8StrToBytes(utf8Key)
let contentBytes = base64js.toByteArray(base64Str)
let plain = sm4.decrypt_ecb(keyBytes, contentBytes)
return Hex.bytesToUtf8Str(plain)
}
/**
* sm4 cbc 加密
* @param utf8Str
* @param utf8Key
* @param utf8Iv
*/
SM4Util.sm4CBCEncrypt = function (utf8Str, utf8Key, utf8Iv) {
if (!utf8Key) {
utf8Key = ‘cmbtest1cmbtest1’
}
if (!utf8Iv) {
utf8Iv = ‘cmbtest1cmbtest1’
}
let sm4 = new SM4()
let keyBytes = Hex.utf8StrToBytes(utf8Key)
let ivBytes = Hex.utf8StrToBytes(utf8Iv)
let contentBytes = Hex.utf8StrToBytes(utf8Str)
let cipher = sm4.encrypt_cbc(keyBytes, ivBytes, contentBytes)
return base64js.fromByteArray(cipher)
}
/**
* sm4 cbc 解密
* @param utf8Str
* @param utf8Key
* @param utf8Iv
*/
SM4Util.sm4CBCDecrypt = function (base64Str, utf8Key, utf8Iv) {
if (!utf8Key) {
utf8Key = ‘cmbtest1cmbtest1’
}
if (!utf8Iv) {
utf8Iv = ‘cmbtest1cmbtest1’
}
let sm4 = new SM4()
let keyBytes = Hex.utf8StrToBytes(utf8Key)
let ivBytes = Hex.utf8StrToBytes(utf8Iv)
let contentBytes = base64js.toByteArray(base64Str)
let plain = sm4.decrypt_cbc(keyBytes, ivBytes, contentBytes)
return Hex.bytesToUtf8Str(plain)
}
module.exports = SM4Util
`@/utils/SM4Util/base64js.js`
/**
* base64js
* base64js.toByteArray(utf8Str)
* base64js.fromByteArray(bytes);
*/
;(function ® {
if (typeof exports === ‘object’ && typeof module !== ‘undefined’) {
module.exports = r()
} else {
if (typeof define === ‘function’ && define.amd) {
define([], r)
} else {
var e
if (typeof window !== ‘undefined’) {
e = window
} else {
if (typeof global !== ‘undefined’) {
e = global
} else {
if (typeof self !== ‘undefined’) {
e = self
} else {
e = this
}
}
}
e.base64js = r()
}
}
})(function () {
var r, e, t
return (function r(e, t, n) {
function o(i, a) {
if (!t[i]) {
if (!e[i]) {
var u = typeof require == ‘function’ && require
if (!a && u) {
return u(i, !0)
}
if (f) {
return f(i, !0)
}
var d = new Error(“Cannot find module '” + i + “'”)
throw ((d.code = ‘MODULE_NOT_FOUND’), d)
}
var c = (t[i] = {
exports: {}
})
e[i][0].call(
c.exports,
function ® {
var t = e[i][1][r]
return o(t ? t : r)
},
c,
c.exports,
r,
e,
t,
n
)
}
return t[i].exports
}
var f = typeof require == ‘function’ && require
for (var i = 0; i < n.length; i++) {
o(n[i])
}
return o
})(
{
‘/’: [
function (r, e, t) {
t.byteLength = c
t.toByteArray = v
t.fromByteArray = s
var n = []
var o = []
var f = typeof Uint8Array !== ‘undefined’ ? Uint8Array : Array
var i = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/’
for (var a = 0, u = i.length; a < u; ++a) {
n[a] = i[a]
o[i.charCodeAt(a)] = a
}
o[‘-’.charCodeAt(0)] = 62
o[‘_’.charCodeAt(0)] = 63
function d(r) {
var e = r.length
if (e % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
return r[e - 2] === '=' ? 2 : r[e - 1] === '=' ? 1 : 0
}
function c(r) {
return (r.length \* 3) / 4 - d(r)
}
function v(r) {
var e, t, n, i, a
var u = r.length
i = d(r)
a = new f((u \* 3) / 4 - i)
t = i > 0 ? u - 4 : u
var c = 0
for (e = 0; e < t; e += 4) {
n =
(o[r.charCodeAt(e)] << 18) |
(o[r.charCodeAt(e + 1)] << 12) |
(o[r.charCodeAt(e + 2)] << 6) |
o[r.charCodeAt(e + 3)]
a[c++] = (n >> 16) & 255
a[c++] = (n >> 8) & 255
a[c++] = n & 255
}
if (i === 2) {
n = (o[r.charCodeAt(e)] << 2) | (o[r.charCodeAt(e + 1)] >> 4)
a[c++] = n & 255
} else {
if (i === 1) {
n = (o[r.charCodeAt(e)] << 10) | (o[r.charCodeAt(e + 1)] << 4) | (o[r.charCodeAt(e + 2)] >> 2)
a[c++] = (n >> 8) & 255
a[c++] = n & 255
}
}
return a
}
function l(r) {
return n[(r >> 18) & 63] + n[(r >> 12) & 63] + n[(r >> 6) & 63] + n[r & 63]
}
function h(r, e, t) {
var n
var o = []
for (var f = e; f < t; f += 3) {
n = (r[f] << 16) + (r[f + 1] << 8) + r[f + 2]
o.push(l(n))
}
return o.join('')
}
function s(r) {
var e
var t = r.length
var o = t % 3
var f = ''
var i = []
var a = 16383
for (var u = 0, d = t - o; u < d; u += a) {
i.push(h(r, u, u + a > d ? d : u + a))
}
if (o === 1) {
e = r[t - 1]
f += n[e >> 2]
f += n[(e << 4) & 63]
f += '=='
} else {
if (o === 2) {
e = (r[t - 2] << 8) + r[t - 1]
f += n[e >> 10]
f += n[(e >> 4) & 63]
f += n[(e << 2) & 63]
f += '='
}
}
i.push(f)
return i.join('')
}
},
{}
]
},
{},
[]
)(‘/’)
})
`@/utils/SM4Util/hex.js`
function Hex() {}
/**
* 数组转为16进制字符串
* @param b 数组
* @param pos 指定位置
* @param len 长度
* @returns {string}
*/
Hex.encode = function (b, pos, len) {
var hexCh = new Array(len * 2)
var hexCode = new Array(‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’)
for (var i = pos, j = 0; i < len + pos; i++, j++) {
hexCh[j] = hexCode[(b[i] & 0xff) >> 4]
hexCh[++j] = hexCode[b[i] & 0x0f]
}
return hexCh.join(‘’)
}
/**
* 16进制字符串转为字节数组
* @param hex
* @returns {any[]|null}
*/
Hex.decode = function (hex) {
if (hex == null || hex == ‘’) {
return null
}
if (hex.length % 2 != 0) {
return null
}
var ascLen = hex.length / 2
var hexCh = this.toCharCodeArray(hex)
var asc = new Array(ascLen)
for (var i = 0; i < ascLen; i++) {
if (hexCh[2 * i] >= 0x30 && hexCh[2 * i] <= 0x39) {
asc[i] = (hexCh[2 * i] - 0x30) << 4
} else if (hexCh[2 * i] >= 0x41 && hexCh[2 * i] <= 0x46) {
//A-F : 0x41-0x46
asc[i] = (hexCh[2 * i] - 0x41 + 10) << 4
} else if (hexCh[2 * i] >= 0x61 && hexCh[2 * i] <= 0x66) {
//a-f : 0x61-0x66
asc[i] = (hexCh[2 * i] - 0x61 + 10) << 4
} else {
return null
}
if (hexCh[2 \* i + 1] >= 0x30 && hexCh[2 \* i + 1] <= 0x39) {
asc[i] = asc[i] | (hexCh[2 \* i + 1] - 0x30)
} else if (hexCh[2 \* i + 1] >= 0x41 && hexCh[2 \* i + 1] <= 0x46) {
asc[i] = asc[i] | (hexCh[2 \* i + 1] - 0x41 + 10)
} else if (hexCh[2 \* i + 1] >= 0x61 && hexCh[2 \* i + 1] <= 0x66) {
asc[i] = asc[i] | (hexCh[2 \* i + 1] - 0x61 + 10)
} else {
return null
}
}
return asc
}
/**
* utf8字符串转为字节数组
* @param utf8Str
* @returns {[]}
*/
Hex.utf8StrToBytes = function (utf8Str) {
var ens = encodeURIComponent(utf8Str)
var es = unescape(ens)
var esLen = es.length
// Convert
var words = []
for (var i = 0; i < esLen; i++) {
words[i] = es.charCodeAt(i)
}
return words
}
/**
* 字节数组转为utf8字符串
* @param bytesArray
* @returns {string}
*/
Hex.bytesToUtf8Str = function (bytesArray) {
var utf8Byte = bytesArray
var latin1Chars = []
for (var i = 0; i < utf8Byte.length; i++) {
latin1Chars.push(String.fromCharCode(utf8Byte[i]))
}
return decodeURIComponent(escape(latin1Chars.join(‘’)))
}
/**
* 16进制字符串转为utf8字符串
* @param utf8Str
* @returns {string}
*/
Hex.hexToUtf8Str = function (utf8Str) {
var utf8Byte = Hex.decode(utf8Str)
var latin1Chars = []
for (var i = 0; i < utf8Byte.length; i++) {
latin1Chars.push(String.fromCharCode(utf8Byte[i]))
}
return decodeURIComponent(escape(latin1Chars.join(‘’)))
}
/**
* utf8字符串转为16进制字符串
* @param utf8Str
* @returns {string}
*/
Hex.utf8StrToHex = function (utf8Str) {
var ens = encodeURIComponent(utf8Str)
var es = unescape(ens)
var esLen = es.length
// Convert
var words = []
for (var i = 0; i < esLen; i++) {
words[i] = es.charCodeAt(i).toString(16)
}
return words.join(‘’)
}
/**
* 字符串中每个字符转为数组中每个元素,数字,字母同Hex.utf8StrToBytes()方法
* @param chs
* @returns {any[]}
*/
Hex.toCharCodeArray = function (chs) {
var chArr = new Array(chs.length)
for (var i = 0; i < chs.length; i++) {
chArr[i] = chs.charCodeAt(i)
}
return chArr
}
module.exports = Hex
`@/utils/SM4Util/sm4.js`
/*
* sm4-1.0.js
*
* Copyright © 2019 RuXing Liang
*/
/**
* @name sm4-1.0.js
* @author RuXing Liang
* @version 1.0.0 (2019-04-19)
*/
function SM4() {
this.sbox = new Array(
0xd6,
0x90,
0xe9,
0xfe,
0xcc,
0xe1,
0x3d,
0xb7,
0x16,
0xb6,
0x14,
0xc2,
0x28,
0xfb,
0x2c,
0x05,
0x2b,
0x67,
0x9a,
0x76,
0x2a,
0xbe,
0x04,
0xc3,
0xaa,
0x44,
0x13,
0x26,
0x49,
0x86,
0x06,
0x99,
0x9c,
0x42,
0x50,
0xf4,
0x91,
0xef,
0x98,
0x7a,
0x33,
0x54,
0x0b,
0x43,
0xed,
0xcf,
0xac,
0x62,
0xe4,
0xb3,
0x1c,
0xa9,
0xc9,
0x08,
0xe8,
0x95,
0x80,
0xdf,
0x94,
0xfa,
0x75,
0x8f,
0x3f,
0xa6,
0x47,
0x07,
0xa7,
0xfc,
0xf3,
0x73,
0x17,
0xba,
0x83,
0x59,
0x3c,
0x19,
0xe6,
0x85,
0x4f,
0xa8,
0x68,
0x6b,
0x81,
0xb2,
0x71,
0x64,
0xda,
0x8b,
0xf8,
0xeb,
0x0f,
0x4b,
0x70,
0x56,
0x9d,
0x35,
0x1e,
0x24,
0x0e,
0x5e,
0x63,
0x58,
0xd1,
0xa2,
0x25,
0x22,
0x7c,
0x3b,
0x01,
0x21,
0x78,
0x87,
0xd4,
0x00,
0x46,
0x57,
0x9f,
0xd3,
0x27,
0x52,
0x4c,
0x36,
0x02,
0xe7,
0xa0,
0xc4,
0xc8,
0x9e,
0xea,
0xbf,
0x8a,
0xd2,
0x40,
0xc7,
0x38,
0xb5,
0xa3,
0xf7,
0xf2,
0xce,
0xf9,
0x61,
0x15,
0xa1,
0xe0,
0xae,
0x5d,
0xa4,
0x9b,
0x34,
0x1a,
0x55,
0xad,
0x93,
0x32,
0x30,
0xf5,
0x8c,
0xb1,
0xe3,
0x1d,
0xf6,
0xe2,
0x2e,
0x82,
0x66,
0xca,
0x60,
0xc0,
0x29,
0x23,
0xab,
0x0d,
0x53,
0x4e,
0x6f,
0xd5,
0xdb,
0x37,
0x45,
0xde,
0xfd,
0x8e,
0x2f,
0x03,
0xff,
0x6a,
0x72,
0x6d,
0x6c,
0x5b,
0x51,
0x8d,
0x1b,
0xaf,
0x92,
0xbb,
0xdd,
0xbc,
0x7f,
0x11,
0xd9,
0x5c,
0x41,
0x1f,
0x10,
0x5a,
0xd8,
0x0a,
0xc1,
0x31,
0x88,
0xa5,
0xcd,
0x7b,
0xbd,
0x2d,
0x74,
0xd0,
0x12,
0xb8,
0xe5,
0xb4,
0xb0,
0x89,
0x69,
0x97,
0x4a,
0x0c,
0x96,
0x77,
0x7e,
0x65,
0xb9,
0xf1,
0x09,
0xc5,
0x6e,
0xc6,
0x84,
0x18,
0xf0,
0x7d,
0xec,
0x3a,
0xdc,
0x4d,
0x20,
0x79,
0xee,
0x5f,
0x3e,
0xd7,
0xcb,
0x39,
0x48
)
this.fk = new Array(0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc)
this.ck = new Array(
0x00070e15,
0x1c232a31,
0x383f464d,
0x545b6269,
0x70777e85,
0x8c939aa1,
0xa8afb6bd,
0xc4cbd2d9,
0xe0e7eef5,
0xfc030a11,
0x181f262d,
0x343b4249,
0x50575e65,
0x6c737a81,
0x888f969d,
0xa4abb2b9,
0xc0c7ced5,
0xdce3eaf1,
0xf8ff060d,
0x141b2229,
0x30373e45,
0x4c535a61,
0x686f767d,
0x848b9299,
0xa0a7aeb5,
0xbcc3cad1,
0xd8dfe6ed,
0xf4fb0209,
0x10171e25,
0x2c333a41,
0x484f565d,
0x646b7279
)
}
SM4.prototype = {
expandKey: function (key) {
var k = new Array(36)
var mk = byteArrayToIntArray(key)
k[0] = mk[0] ^ this.fk[0]
k[1] = mk[1] ^ this.fk[1]
k[2] = mk[2] ^ this.fk[2]
k[3] = mk[3] ^ this.fk[3]
var rk = new Array(32)
for (var i = 0; i < 32; i++) {
k[i + 4] = k[i] ^ this.T1(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ this.ck[i])
rk[i] = k[i + 4]
}
return rk
},
T1: function (ta) {
var rk = 0
var b = new Array(4)
var a = intToByte(ta)
b[0] = this.sbox[a[0] & 0xff]
b[1] = this.sbox[a[1] & 0xff]
b[2] = this.sbox[a[2] & 0xff]
b[3] = this.sbox[a[3] & 0xff]
var bint = byteToInt(b, 0)
var rk = bint ^ ((bint << 13) | (bint >>> (32 - 13))) ^ ((bint << 23) | (bint >>> (32 - 23)))
return rk
},
one_encrypt: function (rk, data) {
var x = new Array(36)
x[0] = byteToInt(data, 0)
x[1] = byteToInt(data, 4)
x[2] = byteToInt(data, 8)
x[3] = byteToInt(data, 12)
for (var i = 0; i < 32; i++) {
x[i + 4] = x[i] ^ this.T0(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ rk[i])
}
var tmpx = new Array(4)
for (var i = 35; i >= 32; i–) {
tmpx[35 - i] = x[i]
}
var xbyte = intArrayToByteArray(tmpx)
return xbyte
},
T0: function (ta) {
var a = intToByte(ta)
var b = new Array(4)
b[0] = this.sbox[a[0] & 0xff]
b[1] = this.sbox[a[1] & 0xff]
b[2] = this.sbox[a[2] & 0xff]
b[3] = this.sbox[a[3] & 0xff]
var bint = byteToInt(b, 0)
var c =
bint ^
((bint << 2) | (bint >>> (32 - 2))) ^
((bint << 10) | (bint >>> (32 - 10))) ^
((bint << 18) | (bint >>> (32 - 18))) ^
((bint << 24) | (bint >>> (32 - 24)))
return c
},
pkcs7padding: function (input, mode) {
if (input == null) {
return null
}
最后
中年危机是真实存在的,即便有技术傍身,还是难免对自己的生存能力产生质疑和焦虑,这些年职业发展,一直在寻求消除焦虑的依靠。
-
技术要深入到什么程度?
-
做久了技术总要转型管理?
-
我能做什么,我想做什么?
-
一技之长,就是深耕你的专业技能,你的专业技术。(重点)
-
独立做事,当你的一技之长达到一定深度的时候,需要开始思考如何独立做事。(创业)
-
拥有事业,选择一份使命,带领团队实现它。(创业)
一技之长分五个层次
-
栈内技术 - 是指你的前端专业领域技术
-
栈外技术 - 是指栈内技术的上下游,领域外的相关专业知识
-
工程经验 - 是建设专业技术体系的“解决方案”
-
带人做事 - 是对团队协作能力的要求
-
业界发声 - 工作经验总结对外分享,与他人交流
永远不要放弃一技之长,它值得你长期
信仰持有
。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue 等等。