RSA加密算法

注: 下文中的 % 符号一律表示取模(mod)操作,而非取余(rem).

取模(Python)

1
2
8 % -5 = -2
-8 % 5 = 2

取余(JavaScript)

1
2
8 % -5 = 3
-8 % 5 = -3

RSA 算法

1 随机选择两个不同的质数 p 和 q.

2 计算 p * q, 记为 n.

3 计算卡迈尔克函数 λ(n).
因为 n = pq, 且 p 和 q 均为质数, 则 λ(n) 为 φ(p) 和 φ(q) 的最小公倍数.
λ(n)=lcm(λ(p),λ(q))=lcm(φ(p),φ(q))=lcm(p1,q1)=/(p1)(q1)/gcd(p1,q1)λ(n) = lcm(λ(p), λ(q)) = lcm(φ(p), φ(q)) = lcm(p -1 , q - 1) = \frac{/(p - 1)(q - 1)/}{gcd(p - 1, q - 1)}

4 随机选择一个整数 e, 满足 1 < e < λ(n) , 并且 e 和 λ(n) 互质.通常会选择 65537 作为 e 的值.

5 计算 e 的模反元素 d, 即 de1 (mod λ(n))de \equiv 1 \ (mod \ λ(n)).

6 将 n 和 e 作为 公钥, n 和 d 作为私钥.

加密: c(m)=me mod nc(m) = m^e \ mod \ n

解密: m=cd mod nm = c^d \ mod \ n

instanceof 与 Object.isPrototypeOf 的区别

Aobj instanceof Bfunction // Bfunction.prototype 是否在 Aobj.__proto__ (A 的原型链)上 ?
Aobj.isPrototypeOf(Bobj) // Aobj 是否在 Bobj.__proto__ (B 的原型链)上?

instanceof 用于判断"左侧的对象"是否是"右侧的构造函数"生成的实例.

相当于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function instance(Aobj, Bfunction) {
let proto = Aobj.__proto__;
while (proto) {
if (proto === Bfunction.prototype) {
return true;
} else {
proto = proto.__proto__;
}
}
return false;
}

class Parent {}
class Child extends Parent {}
class Grandson extends Child {}

var c = new Child();
instance(c, Parent); // true
instance({}, Parent); // false
instance(c, Object); // true

var g = new Grandson();
instance(g, Parent); // true

class

Es6 开始引入了 class 关键字,其本质是基于构造函数和原型链继承的语法糖.

创建 class

有两种方法创建 class, class declartions(类声明) 和 class expression(类表达式).

class declarations

1
class Foo {}

class declarations 必须有类名,否则会报错 SyntaxError.

1
class {} // SyntaxError: Unexpected token {

Sequelize

Sequelize 是基于 Node 的 ORM 库, 支持的数据库有 Postgres | MySQL | MariaDB, SQLite | Microsoft SQL Server.
Sequelize 将数据库键值对映射成对象, 将增删改查操作映射成方法,抹平了不同数据库间的语法区别.

hello world

安装 Sequelize

1
2
yarn add sequelize
yarn add sqlite3

child_process

本文环境:

  • windows
  • node v12.16.1

本文使用的模块:

1
2
3
const cp = require("child_process");
const path = require("path");
const iconv = require("iconv-lite");

child_process 模块提供了 4 种方法创建子进程:

  • child_process.spawn
  • child_process.execFile
  • child_process.exec
  • child_process.fork

除此之外, 还用 3 种同步方法:

  • child_process.spawnSync
  • child_process.execFileSync
  • child_process.execSync

puppeteer (2) 在页面环境下执行 Js 代码

执行 js 函数

page.evaluate(pageFunction[, ...args])

  • pageFunction 在页面环境中执行的函数
  • args 参数
1
2
3
4
5
6
7
8
9
10
11
12
13
const puppeteer = require("puppeteer");
async function init() {
const browser = await puppeteer.launch({
headless: false,
args: ['--proxy-server="direct://"', "--proxy-bypass-list=*"],
});
const page = await browser.newPage();

await page.evaluate(async () => {
console.log("hello world");
});
}
init();

快排

平均时间复杂度

nT(n)=[T(0)+T(n1)+cn+T(1)+T(n2)+cn++T(n1)+T(0)+cn]=[T(0)+T(1)++T(n1)]+[T(n1)+T(n2)++T(0)]+cn2=2[T(0)+T(1)++T(n1)]合并+cn2=2j=0n1T(j)+cn2 \begin{aligned} nT(n) &= \begin{bmatrix} T(0) + T(n - 1) + cn \\ + \\ T(1) + T(n - 2) + cn \\ + \\ \vdots \\ + \\ T(n - 1) + T(0) + cn \end{bmatrix} \\ \\ &= [T(0) + T(1) + \dots + T(n-1)] + [T(n-1) + T(n-2) + \dots + T(0)] + cn^2\\ \\ &= 2\underbrace{[T(0) + T(1) + \dots + T(n-1)]}_{\text{合并}} + cn^2 \\ \\ &= 2 \sum_{j=0}^{n-1} T(j) + cn^2 \end{aligned}

Cookie

HTTP 协议是"无状态的",但需要通过某些标记来判断用户身份,Cookie 为此而生.
Cookie 是保存在浏览器上的一段数据,常用来识别用户身份.当浏览器向服务器发出 HTTP 请求时,会自动携带 Cookie.
修改 Cookie 的方法有两种, 在服务器发送响应数据时设置 response headers,或在浏览器中执行 Js.
浏览器 Cookie 可以储存的数据有条数和大小限制.一般限制为50条以下 , 大小不超过4096bytes.

Cookie 有大小限制,且浏览器会自动发送 Cookie,最好不要把 Cookie 当作 LocalStore 使用.

5 Longest Palindromic Substring

题目

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

Example 1:

1
2
3
4
5
6
7
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:

Input: "cbbd"
Output: "bb"

解题思路

从左向右依次遍历字符串.
以当前字符(假设回文数为基数长度)或当前字符和下一个字符(假设回文数为偶数长度)为回文数中心, 向左右两侧搜索.

时间复杂度 O(n2)O(n^2)