js逆向之常用算法
[Python]
encode & decode
from urllib import parse # url进行编码与解码
url = '你好啊' url_encode = parse.quote(url)
print('url编码后:', url_encode) url_decode = parse.unquote(url_encode)
print('url解码后:', url_decode) url_encode2 = parse.quote_plus(url)
print('url2编码后:', url_encode2) url_decode2 = parse.unquote_plus(url_encode2)
print('url2解码后:', url_decode2) request_params = {
"id": 1,
"name": "lanlang"
}
param_encode = parse.urlencode(request_params)
print('param_encode:', param_encode) # id=1&name=lanlang
param_decode = parse.unquote(param_encode)
print('param_decode:', param_decode)
md5
import hashlib msg = 'hello, MD5摘要算法'
m = hashlib.md5()
m.update(msg.encode('utf-8'))
md5_data = m.hexdigest() # 摘要
print('md5后的数据:', md5_data)
# acffb8e4d57563e9168fd0376fa9da4c
base64
import base64 # msg = 'hello, python'
msg = '你好哦' # 编码
msg_byte = msg.encode()
print('文本字节:', msg_byte)
base64_encoded = base64.b64encode(msg_byte)
print('base64_encoded:', base64_encoded.decode()) # 解码
base64_decoded = base64.b64decode(base64_encoded)
print('base64_decoded:', base64_decoded, base64_decoded.decode())
aes
pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes # key = get_random_bytes(16) # 生成随机的16字节密钥
key = b'1234567897891234' plaintext = b'Hello, world!' # 加密数据 cipher = AES.new(key, AES.MODE_ECB) # 创建 AES 加密器对象
padded_plaintext = pad(plaintext, AES.block_size) # 填充明文数据 ciphertext = cipher.encrypt(padded_plaintext) # 加密 decrypted = cipher.decrypt(ciphertext) # 解密
decrypted_data = unpad(decrypted, AES.block_size) # 去除填充 print('原始数据:', plaintext)
print('加密后:', ciphertext.hex())
print('解密后:', decrypted_data)
exit(0) data = b'Hello, world!'
# # 随机生成16字节(即128位)的加密密钥
# key = get_random_bytes(16)
# iv = get_random_bytes(16) key = iv = b'1234567897891234' # 使用CBC模式
cipher = AES.new(key, AES.MODE_CBC, iv)
# 对内容进行加密,pad函数用于分组和填充
encrypted_data = cipher.encrypt(pad(data, AES.block_size)) print('AES加密后数据:', encrypted_data, encrypted_data.hex())
# 需要重新new一个,否则会出现错误, 不能在encrypt之后,再进行decrypt
cipher_new = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher_new.decrypt(encrypted_data)
decrypted_data = unpad(decrypted, AES.block_size)
print('AES解密后数据:', decrypted_data.decode()) # 使用模块pycryptdome --> pip install pycryptodome
rsa:
生成秘钥对
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP key = RSA.generate(2048) # 私钥
private_key = key.export_key()
with open('private_key.pem', 'wb') as f:
f.write(private_key) # 公钥
public_key = key.public_key().export_key()
with open('public_key.pem', 'wb') as f:
f.write(public_key)
encrypt & decrypt
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP # 加密
data = b'Hello, world!'
with open('public_key.pem', 'rb') as f:
public_key = RSA.import_key(f.read()) cipher = PKCS1_OAEP.new(public_key) encrypted_data = cipher.encrypt(data) print('encrypted_data:', encrypted_data) # 解密
with open('private_key.pem', 'rb') as f:
private_key = RSA.import_key(f.read()) cipher = PKCS1_OAEP.new(private_key) decrypted_data = cipher.decrypt(encrypted_data) print('decrypted_data:', decrypted_data.decode())
pycryptodome模块更多参考:
- https://www.jb51.net/python/3059815tp.htm
[Nodejs]
urlencode/urldecode
const query = '日语';
encodeUrl = encodeURIComponent(query)
console.log('url编码:', encodeUrl) // %E6%97%A5%E8%AF%AD
decodeUrl = decodeURIComponent(encodeUrl)
console.log('url解密:', decodeUrl)
md5:
npm install crypto
const crypt = require('crypto') let msg = 'hello, MD5摘要算法' let md5 = crypt.createHash('md5') md5_data = md5.update(msg).digest('hex')
console.log('Md5后的数据:', md5_data)
base64:
msg = '你好哦' let buff = Buffer.from(msg, 'utf-8') let base64_encoded = buff.toString('base64') console.log('base64_encoded:', base64_encoded)
// 5L2g5aW95ZOm let buff2 = Buffer.from(base64_encoded, 'base64')
let base64_decoded = buff2.toString('utf-8')
console.log('base64_decoded:', base64_decoded)
aes:
const crypt = require('crypto') function aesEncrypt(data, key, iv) {
const cipher = crypt.createCipheriv('aes128', key, iv);
var crypted = cipher.update(data, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
} function aesDecrypt(encrypted, key, iv) {
const decipher = crypt.createDecipheriv('aes128', key, iv);
var decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
} key = '1234567897891234'
iv = '1234567897891234'
data = "Hello, world!"
encrypt_data = aesEncrypt(data, key, iv)
console.log('加密后数据:', encrypt_data) encrypt_data = 'f4d236a9e916d66cf064686f4eb67c03'
decrypt_data = aesDecrypt(encrypt_data, key, iv)
console.log('解密后数据:', decrypt_data)
另外还有crypto-js支持使用
介绍
CryptoJS是一个JavaScript的加解密的工具包。它支持多种的算法:MD5、SHA1、SHA2、SHA3、RIPEMD-160
哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES
加解密。
散列算法
MD5
MD5
是一种广泛使用的散列函数。它被用于各种安全应用,也通常用于校验文件的完整性。但MD5
不耐碰撞攻击,因此不适用于SSL
证书或数字签名。
var hash = CryptoJS.MD5("Message");
SHA-1
SHA
散列函数由美国国家安全局 (NSA) 设计。SHA-1
是现有 SHA
散列函数中最成熟的,它用于各种安全应用程序和协议。但随着新攻击的发现或改进,SHA-1
的抗攻击能力一直在减弱。
var hash = CryptoJS.SHA1("Message");
SHA-2
SHA-224、SHA-256、SHA-384
,和SHA-512
合称为SHA-2
。SHA-256
是SHA-2
集合中的四个变体之一。虽然它提供了更好的安全性,但是它的应用不如SHA-1广泛。
var hash = CryptoJS.SHA256("Message");
SHA-512
在很大程度上与SHA-256
相同,但在64位计算机上SHA-512
比SHA-256
更快(因为它们在内部使用64位算术);在8位,16位和32位计算机上,SHA-256
比SHA-512
更快。
var hash = CryptoJS.SHA512("Message");
CryptoJS
还支持SHA-224
和SHA-384
,这两个版本大致相同,分别是SHA-256
和SHA-512
的删减版本。
SHA-3
SHA-3
是第三代安全散列算法(Secure Hash Algorithm 3)
var hash = CryptoJS.SHA3("Message");
SHA-3
可以配置输出散列长度为224,256,384或512位,默认为512位。
var hash = CryptoJS.SHA3("Message", { outputLength: 512 });
var hash = CryptoJS.SHA3("Message", { outputLength: 384 });
var hash = CryptoJS.SHA3("Message", { outputLength: 256 });
var hash = CryptoJS.SHA3("Message", { outputLength: 224 });
RIPEMD-160
var hash = CryptoJS.RIPEMD160("Message");
散列输入
散列算法接受输入字符串或WordArray
实例。WordArray
对象表示一个32位“单词数组”。当你传入一个字符串时,它会自动转换为编码为UTF-8
的WordArray
。
散列输出
返回的散列不是字符串,它是一个WordArray
对象。当您在字符串上下文中使用WordArray
对象时,它会自动转换为十六进制字符串。
var hash = CryptoJS.SHA256("Message");
typeof hash
> "object";
hash
> "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91";
使用toString
方法并传入编码格式,可以将WordArray
对象转换为其他编码格式
var hash = CryptoJS.SHA256("Message")
hash.toString(CryptoJS.enc.Base64)
> "L3dmip37+NWEi57rSnFFypTG7ZI25Kdz9tyvpRMrL5E=";
hash.toString(CryptoJS.enc.Hex)
> "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91";
渐进式散列
var sha256 = CryptoJS.algo.SHA256.create();
sha256.update("Message Part 1");
sha256.update("Message Part 2");
sha256.update("Message Part 3");
var hash = sha256.finalize();
HMAC
HMAC
是一种使用加密散列函数进行消息认证的机制,可以与任何迭代密码散列函数结合使用。
var hash = CryptoJS.HmacMD5("Message", "Secret Passphrase");
var hash = CryptoJS.HmacSHA1("Message", "Secret Passphrase");
var hash = CryptoJS.HmacSHA256("Message", "Secret Passphrase");
var hash = CryptoJS.HmacSHA512("Message", "Secret Passphrase");
渐进式HMAC散列
var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, "Secret Passphrase");
hmac.update("Message Part 1");
hmac.update("Message Part 2");
hmac.update("Message Part 3");
var hash = hmac.finalize();
PBKDF2
PBKDF2
是一个用来对用户口令(password)进行加密的函数。在密码学的许多应用中,用户安全性最终取决于用户口令,由于用户口令通常不能直接用作密钥,因此需要进行一些处理。
它的基本原理是通过一个伪随机函数(例如HMAC
函数),把明文和一个盐值作为输入参数,,生成一个散列值,然后将这个散列值作为一个加密key,应用到后续的加密过程中,以此类推,将这个过程重复很多次,从而增加了密码破解的难度,这个过程也被称为是密码加强。如果重复的次数足够大,破解的成本就会变得很高。
Salt
表示盐值,一个随机数iterations
操作次数
var salt = CryptoJS.lib.WordArray.random(128 / 8);
var key128Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, {
keySize: 128 / 32
});
var key256Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, {
keySize: 256 / 32
});
var key512Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, {
keySize: 512 / 32
});
var key512Bits1000Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, {
keySize: 512 / 32,
iterations: 1000
});
加密
加密算法
加密函数的参数是:(明文字符串, 密钥字符串,可选参数对象),返回密文字符串。
加密函数是:Cryptojs.AES.encrypt
,Cryptojs.DES.encrypt``,Cryptojs.Rabbit.encrypt
,Cryptojs.RC4.encrypt
,Cryptojs.TripleDES.encrypt
解密函数的参数是:(密文字符串, 密钥字符串,可选参数对象),返回的结果必须用.toString(CryptoJS.enc.Utf8)
转为明文。
解密函数是:CryptoJS.AES.decrypt
,CryptoJS.DES.decrypt
,CryptoJS.Rabbit.decrypt
,CryptoJS.RC4.decrypt
,CryptoJS.TripleDES.decrypt
其中可选参数对象常用属性:
mode
:加密模式 【CBC ECB CFB OFB CTRGladman(CTR)】paddig
:填充方式 【 NoPadding ZeroPadding Pkcs7(Pkcs5) Iso10126 Iso97971 AnsiX923】vi
: 偏移向量formatter
:自定义格式
AES
AES
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
CryptoJS
支持AES-128、AES-192
和AES-256
。密钥的长度决定了AES加密
的轮数。
DES,三重DES
DES
是以前比较重要的加密算法,但由于密钥长度太短,安全性不够。
var encrypted = CryptoJS.DES.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.DES.decrypt(encrypted, "Secret Passphrase");
三重DES
是为了增加DES的强度,将DES重复3次所得到的一种密码算法,具有足够的安全性。
var encrypted = CryptoJS.TripleDES.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.TripleDES.decrypt(encrypted, "Secret Passphrase");
Rabbit
Rabbit
是一种高速流密码,于 2003 年在 FSE 研讨会上首次提出。 Rabbit
使用一个 128 位密钥和一个 64 位初始化向量。 该加密算法的核心组件是一个位流生成器,该流生成器每次迭代都会加密 128 个消息位。
var encrypted = CryptoJS.Rabbit.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.Rabbit.decrypt(encrypted, "Secret Passphrase");
RC4, RC4Drop
RC4
算法是Ron Rivest
为RSA公司
在1987年设计的一种流密码,作为RSA
的商业机密直到1994年才被匿名公布于Internet
。RC4
被用于为网络浏览器和服务器间通信而制定的SSL/TLS
(安全套接字协议/传输层安全协议)标准中,以及作为IEEE 801.11无线局域网标准一部分的WEP
(Wired Equivalent Privacy)协议和新的WiFi受保护访问协议(WAP)中。从这些应用来看,RC4
构成了当今网络通信的非常重要的部分,因此这个算法非常重要。
var encrypted = CryptoJS.RC4.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.RC4.decrypt(encrypted, "Secret Passphrase");
后来研究者发现,密钥流初始的若干字节有偏移问题,泄露了密钥信息,被很多用户弃用。当然,我们可以通过丢弃密钥流的初始若干字节来防御这种攻击,这种改进的算法也被称为RC4-drop
。RC4-drop
可以用drop
属性设置丢弃字节值。
var encrypted = CryptoJS.RC4Drop.encrypt("Message", "Secret Passphrase");
var encrypted = CryptoJS.RC4Drop.encrypt("Message", "Secret Passphrase", {
drop: 3072 / 4
});
var decrypted = CryptoJS.RC4Drop.decrypt(encrypted, "Secret Passphrase", {
drop: 3072 / 4
});
设置密钥(key)和偏移量(iv)
var key = CryptoJS.enc.Hex.parse("000102030405060708090a0b0c0d0e0f");
var iv = CryptoJS.enc.Hex.parse("101112131415161718191a1b1c1d1e1f");
var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
加密模式和填充方式
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase", {
mode: CryptoJS.mode.CFB,
padding: CryptoJS.pad.AnsiX923
});
CryptoJS
支持以下加密模式:
- CBC (the default)
- CFB
- CTR
- OFB
- ECB
CryptoJS
支持以下填充方式:
- Pkcs7 (the default)
- Iso97971
- AnsiX923
- Iso10126
- ZeroPadding
- NoPadding
加密输入
对于明文消息,加密算法接受输入字符串或CryptoJS.lib.WordArray
实例。
对于密钥key,当您输入一个字符串时,它将用于生成密钥和IV。您可以输入实际密钥的WordArray
对象和实际的IV
。
对于密文,密码算法接受输入字符串或CryptoJS.lib.CipherParams
的实例。CipherParams
对象表示一组参数,如IV、salt
和原始密文本身。当您输入字符串时,它会根据可配置的格式策略自动转换为CipherParams
对象。
加密输出
解密后得到的明文是一个WordArray
对象。详见散列的输出。
加密后得到的密文不是字符串,它是一个CipherParams
对象。通过CipherParams
对象,您可以拿到加密期间使用的所有参数。当您在字符串上下文中使用CipherParams
对象时,它会根据格式策略自动转换为字符串。默认是openssl
兼容的格式。
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
encrypted.key
> "74eb593087a982e2a6f5dded54ecd96d1fd0f3d44a58728cdcd40c55227522223 ";
encrypted.iv
> "7781157e2629b094f0e3dd48c4d786115";
encrypted.salt
> "7a25f9132ec6a8b34";
encrypted.ciphertext
> "73e54154a15d1beeb509d9e12f1e462a0";
encrypted
> "U2FsdGVkX1+iX5Ey7GqLND5UFUoV0b7rUJ2eEvHkYqA=";
您可以定义自己的格式,以便与其他加密实现兼容。format
有两个对象方法stringify
和parse
,在CipherParams
对象和密文字符串之间进行转换。
下面是编写JSON
格式化的方法:
var JsonFormatter = {
stringify: function(cipherParams) {
// 创建ciphertext对象
var jsonObj = { ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) };
//可选添加 iv 和 salt
if (cipherParams.iv) {
jsonObj.iv = cipherParams.iv.toString();
}
if (cipherParams.salt) {
jsonObj.s = cipherParams.salt.toString();
}
// 转换成json字符串
return JSON.stringify(jsonObj);
},
parse: function(jsonStr) {
// 转换成json格式
var jsonObj = JSON.parse(jsonStr);
// extract ciphertext from json object, and create cipher params object
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct)
});
// 可选提取 iv 和 salt
if (jsonObj.iv) {
cipherParams.iv = CryptoJS.enc.Hex.parse(jsonObj.iv);
}
if (jsonObj.s) {
cipherParams.salt = CryptoJS.enc.Hex.parse(jsonObj.s);
}
return cipherParams;
}
};
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase", {
format: JsonFormatter
});
encrypted
> {
ct: "tZ4MsEnfbcDOwqau68aOrQ==",
iv: "8a8c8fd8fe33743d3638737ea4a00698",
s: "ba06373c8f57179c"
};
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase", {
format: JsonFormatter
});
decrypted.toString(CryptoJS.enc.Utf8)
> "Message";
渐进式加密
var key = CryptoJS.enc.Hex.parse("000102030405060708090a0b0c0d0e0f");
var iv = CryptoJS.enc.Hex.parse("101112131415161718191a1b1c1d1e1f");
// encrypt加密
var aesEncryptor = CryptoJS.algo.AES.createEncryptor(key, { iv: iv });
var ciphertextPart1 = aesEncryptor.process("Message Part 1");
var ciphertextPart2 = aesEncryptor.process("Message Part 2");
var ciphertextPart3 = aesEncryptor.process("Message Part 3");
var ciphertextPart4 = aesEncryptor.finalize();
// decrypt解密
var aesDecryptor = CryptoJS.algo.AES.createDecryptor(key, { iv: iv });
var plaintextPart1 = aesDecryptor.process(ciphertextPart1);
var plaintextPart2 = aesDecryptor.process(ciphertextPart2);
var plaintextPart3 = aesDecryptor.process(ciphertextPart3);
var plaintextPart4 = aesDecryptor.process(ciphertextPart4);
var plaintextPart5 = aesDecryptor.finalize();
可行性操作
使用OpenSSL加密拿到openSSLEncrypted:
openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64
使用CryptoJS解密:
var decrypted = CryptoJS.AES.decrypt(openSSLEncrypted, "Secret Passphrase");
编码器
CryptoJS可以将Base64、Latin1或Hex等编码格式转换为WordArray对象,反之亦然。
// Base64字符串 > WordArray对象
var words = CryptoJS.enc.Base64.parse("SGVsbG8sIFdvcmxkIQ==");
// WordArray对象 > Base64字符串
var base64 = CryptoJS.enc.Base64.stringify(words);
// Latin1字符串 > WordArray对象
var words = CryptoJS.enc.Latin1.parse("Hello, World!");
// WordArray对象 > Latin1
var latin1 = CryptoJS.enc.Latin1.stringify(words);
// 16进制 > WordArray对象
var words = CryptoJS.enc.Hex.parse("48656c6c6f2c20576f726c6421");
// WordArray对象 > 16进制
var hex = CryptoJS.enc.Hex.stringify(words);
// utf8 > WordArray对象
var words = CryptoJS.enc.Utf8.parse("");
// WordArray对象 > utf8
var utf8 = CryptoJS.enc.Utf8.stringify(words);
// utf16 > WordArray对象
var words = CryptoJS.enc.Utf16.parse("Hello, World!");
// WordArray对象 > utf16
var utf16 = CryptoJS.enc.Utf16.stringify(words);
// utf16le > WordArray对象
var words = CryptoJS.enc.Utf16LE.parse("Hello, World!");
// WordArray对象 > utf16le
var utf16 = CryptoJS.enc.Utf16LE.stringify(words);
使用方法
1、安装
npm install crypto-js --save-dev
yarn add crypto-js --dev
// 或者下载js文件https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js
2、在node中使用
ES6方式:
import sha256 from 'crypto-js/sha256';
import hmacSHA512 from 'crypto-js/hmac-sha512';
import Base64 from 'crypto-js/enc-base64';
const message, nonce, path, privateKey;
const hashDigest = sha256(nonce + message);
const hmacDigest = Base64.stringify(hmacSHA512(path + hashDigest, privateKey));
非ES6方式:
var AES = require("crypto-js/aes");
var SHA256 = require("crypto-js/sha256");
...
console.log(SHA256("Message"));
可以引入整个CryptoJS
,这样可以使用所有加解密的方法
var CryptoJS = require("crypto-js");
console.log(CryptoJS.HmacSHA1("Message", "Key"));
3、在浏览器客户端使用
RequireJS方式:
按需导入CryptoJS子模块方法
require.config({
packages: [
{
name: 'crypto-js',
location: 'path-to/bower_components/crypto-js',
main: 'index'
}
]
});
require(["crypto-js/aes", "crypto-js/sha256"], function (AES, SHA256) {
console.log(SHA256("Message"));
});
或者导入整个CryptoJS
模块,这样可以使用所有加解密的方法
require.config({
paths: {
'crypto-js': 'path-to/bower_components/crypto-js/crypto-js'
}
});
require(["crypto-js"], function (CryptoJS) {
console.log(CryptoJS.HmacSHA1("Message", "Key"));
});
非RequireJS方式:
<script type="text/javascript" src="path-to/bower_components/crypto-js/crypto-js.js"></script>
<script type="text/javascript">
var encrypted = CryptoJS.AES(...);
var encrypted = CryptoJS.SHA256(...);
</script>
4、AES加密例子
纯文本加密
var CryptoJS = require("crypto-js");
// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString();
// Decrypt
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
var originalText = bytes.toString(CryptoJS.enc.Utf8);
console.log(originalText); // 输出'my message'
对象加密
var CryptoJS = require("crypto-js");
var data = [{id: 1}, {id: 2}]
// Encrypt
var ciphertext = CryptoJS.AES.encrypt(JSON.stringify(data), 'secret key 123').toString();
// Decrypt
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
var decryptedData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
console.log(decryptedData); //输出 [{id: 1}, {id: 2}]
js逆向之常用算法的更多相关文章
- 爬虫05 /js加密/js逆向、常用抓包工具、移动端数据爬取
爬虫05 /js加密/js逆向.常用抓包工具.移动端数据爬取 目录 爬虫05 /js加密/js逆向.常用抓包工具.移动端数据爬取 1. js加密.js逆向:案例1 2. js加密.js逆向:案例2 3 ...
- 「面试指南」JS数组Array常用算法,Array算法的一般解答思路
先看一道面试题 在 LeetCode 中有这么一道简单的数组算法题: // 给定一个整数数组 nums 和一个目标值 target, // 请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下 ...
- 这个爬虫JS逆向加密任务,你还不来试试?逆向入门级,适合一定爬虫基础的人
友情提示:在博客园更新比较慢,有兴趣的关注知识图谱与大数据公众号吧.这次选择苏宁易购登录密码加密,如能调试出来代表你具备了一定的JS逆向能力,初学者建议跟着内容调试一波,尽量独自将JS代码抠出来,实在 ...
- JS逆向-抠代码的第一天【手把手学会抠代码】
首先声明,本人经过无数次摸爬滚打及翻阅各类资料,理论知识极其丰富,但是抠代码怎么都抠不会. 无奈之下,只能承认:这个活,需要熟练度. 本文仅对部分参数进行解析,有需要调用,请自行根据现实情况调整. 第 ...
- GIS常用算法
目录 1.常用算法 1.1.计算两经纬度点之间的距离 1.2.根据已知线段以及到起点距离,求目标点坐标 1.3.已知点.线段,求垂足 1.4.线段上距离目标点最近的点 1.5.点缓冲 1.6.点和面关 ...
- 总结Objective-c常用算法
今天是星期天,想睡到10点起床,结果认为自己太奢侈了,不能这么做,于是把闹钟设置成了6:30:结果终于9:36醒了,起床,无缘无故迟了,好吧,就算太累了吧,周天就原谅自己一回.终于到了中午 ...
- Atitit 编程语言常用算法attilax总结
Atitit 编程语言常用算法attilax总结 1. 编译算法分类and 数据操作算法.1 1.1. Tab driver stat 状态转换表格算法1 1.2. Nest case 词法分析 ...
- GJM : 数据结构 - 轻松看懂机器学习十大常用算法 [转载]
转载请联系原文作者 需要获得授权,非法转载 原文作者将享受侵权诉讼 文/不会停的蜗牛(简书作者)原文链接:http://www.jianshu.com/p/55a67c12d3e9 通过本篇文章可以 ...
- ACM常用算法及练习(2)
ACM常用算法及练习 知识类型 重要度 容易度 应掌握度 典型题 其他 数据结构(5) 链表 ★★☆ ★★★ ★★☆ 栈 stack ★★★ ★★★ ★★★ HLoj120 ...
- ACM常用算法及练习(1)
ACM常用算法及练习 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来. 1.最短 ...
随机推荐
- AI图像放大工具,图片放大无所不能
AI图像放大工具,如ESRGAN,对于提高由Stable Diffusion生成的AI图像质量至关重要.它们被广泛使用,以至于许多Stable Diffusion的图形用户界面(GUI)都内置了支持. ...
- 【YashanDB知识库】自关联外键插入数据时报错:YAS-02033 foreign key constraint violated parent key not found
问题现象 使用如下的sql语句创建自关联外键表: drop table self_f_key; create table self_f_key(t1 number primary key not nu ...
- CSS – 实战 Font
前言 这篇想整理一下在网页开发中, 字体是如果被处理的. 先看完: 平面设计 – 字体 CSS – Font / Text 属性 CSS – Font Family CSS – word-break, ...
- 全网最适合入门的面向对象编程教程:48 Python函数方法与接口-位置参数、默认参数、可变参数和关键字参数
全网最适合入门的面向对象编程教程:48 Python 函数方法与接口-位置参数.默认参数.可变参数和关键字参数 摘要: 在 Python 中,函数可以接受多种不同类型的参数,包括位置参数.默认参数.可 ...
- iManager微服务(云套件)配置https证书流程步骤
本文使用的是10.1版本,需要手动去配置证书,未来版本会考虑进行界面化配置. 一.提前准备 1. 证书需要准备三个文件 *.key *.crt *.keystore 2. 需要知道自己创建的微服务是哪 ...
- LeetCode 730. Count Different Palindromic Subsequences (区间DP)
题意 给一个字符串S,求它所有子序列中不同非空回文串的数量.字符串由 'a' 'b' 'c' 'd' 四个字母组成. 由于题目要求的是不同回文串. abba 的回文串子序列为 a,b,aba,abba ...
- centos7 nginx+php7yum安装
centos7 nginx+php7yum安装. 一.安装nginx 1.安装yum源 rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/ ...
- linux kernel 中tracing buffer
Linux内核的tracing buffer是一种用于存储内核跟踪数据的特殊缓冲区.它用于记录内核中发生的事件和活动,以帮助开发人员进行性能分析和故障排查.该缓冲区可以在内核运行时启用,并且可以通过特 ...
- 数据库周刊33丨腾讯Tbase新版本发布;“2020数据技术嘉年华”有奖话题遴选;阿里云技术面试题;APEX 实现数据库自动巡检;MYSQL OCP题库……
摘要:墨天轮数据库周刊第33期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.中国移动国产OLTP数据库中标公告:南大金仓阿里,万里开源中兴 分获大单[摘要]近日,中国 ...
- QToss:基于.NET架构的跨境电商的工具,助力企业实现智能数据营销
2024年10月13日下午参加了一场在深圳举办的跨境电商大佬们的聚会,现场参加的人数上千人. 大会分享嘉宾中有位来自美国的,他告诉我们不用担心美国政府会把TikTok禁掉,TikTok在全世界都很受欢 ...