提交 1e269b8e 编写于 作者: 码梦天涯's avatar 码梦天涯

add to git

上级
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"warnOnUnsupportedTypeScriptVersion": false,
"ecmaVersion": 6,
"sourceType": "module"
},
"env": {
"browser": false,
"node": true,
"es6": true
},
"plugins": [
"@typescript-eslint", "jsdoc", "no-null", "import"
],
"rules": {
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": "error",
"camelcase": "off",
"@typescript-eslint/camelcase": ["error", { "properties": "never", "allow": ["^[A-Za-z][a-zA-Za-z]+_[A-Za-z]+$"] }],
"@typescript-eslint/class-name-casing": "error",
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
"@typescript-eslint/interface-name-prefix": "error",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-this-alias": "error",
"@typescript-eslint/prefer-for-of": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/prefer-namespace-keyword": "error",
"quotes": "off",
"@typescript-eslint/quotes": ["error", "double", { "avoidEscape": true, "allowTemplateLiterals": true }],
"semi": "off",
"@typescript-eslint/semi": "error",
"@typescript-eslint/triple-slash-reference": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unified-signatures": "error",
// scripts/eslint/rules
/*"object-literal-surrounding-space": "error",
"no-type-assertion-whitespace": "error",
"type-operator-spacing": "error",
"only-arrow-functions": ["error", {
"allowNamedFunctions": true ,
"allowDeclarations": true
}],
"no-double-space": "error",
"boolean-trivia": "error",
"no-in-operator": "error",
"simple-indent": "error",
"debug-assert": "error",
"no-keywords": "error",
"one-namespace-per-file": "error",*/
// eslint-plugin-import
"import/no-extraneous-dependencies": ["error", { "optionalDependencies": false }],
// eslint-plugin-no-null
"no-null/no-null": "error",
// eslint-plugin-jsdoc
"jsdoc/check-alignment": "error",
// eslint
// "brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
"constructor-super": "error",
"curly": ["error", "multi-line"],
"dot-notation": "error",
"eqeqeq": "error",
"linebreak-style": ["error", "windows"],
"new-parens": "error",
"no-caller": "error",
"no-duplicate-case": "error",
"no-duplicate-imports": "error",
"no-empty": "error",
"no-eval": "error",
"no-extra-bind": "error",
"no-fallthrough": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-return-await": "error",
"no-restricted-globals": ["error",
{ "name": "setTimeout" },
{ "name": "clearTimeout" },
{ "name": "setInterval" },
{ "name": "clearInterval" },
{ "name": "setImmediate" },
{ "name": "clearImmediate" }
],
"no-sparse-arrays": "error",
"no-template-curly-in-string": "error",
"no-throw-literal": "error",
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-unsafe-finally": "error",
"no-unused-expressions": ["error", { "allowTernary": true }],
"no-unused-labels": "error",
"no-var": "error",
"object-shorthand": "off",
"prefer-const": "error",
"prefer-object-spread": "error",
"quote-props": ["error", "consistent-as-needed"],
"space-in-parens": "error",
"unicode-bom": ["error", "never"],
"use-isnan": "error"
}
}
node_modules
.idea
*.log
yarn.lock
package-lock.json
{
"name": "util-container",
"version": "1.0.0",
"description": "业务常用util合集",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^12.12.21",
"@typescript-eslint/eslint-plugin": "2.3.2",
"@typescript-eslint/experimental-utils": "2.3.2",
"@typescript-eslint/parser": "2.3.2",
"eslint": "6.5.1",
"eslint-formatter-autolinkable-stylish": "1.0.3",
"eslint-plugin-import": "2.18.2",
"eslint-plugin-jsdoc": "15.9.9",
"eslint-plugin-no-null": "1.0.2",
"typescript": "^3.7.3"
}
}
export namespace DateUtil {
/** 始终保持将字符串转换为当地时区的日期对象 */
export function parse(str: string): Date {
if (!/^\d{4}-\d{2}-\d{2}(| \d{2}:\d{2}:\d{2}(| \+\d{4}))$/.test(str)) {
throw Error(`cannot parse string: '${str}'`);
}
// 直接调用Date.parse(),会因为内容,导致不确定有没有加时区
// 所以,这里将只有日期的情况设定为0点,并且设定为0时区
if (str.length === 10) { // 'yyyy-MM-dd' 的情况长度为10
str = str + " 00:00:00";
}
if (str.length === 19) { // 'yyyy-MM-dd HH:mm:ss' 的情况长度为19
str = str + " +0000";
}
// 加上与0时区的时间差
return new Date(Date.parse(str) + new Date().getTimezoneOffset() * 60 * 1000);
}
type flexKey = "date" | "month" | "year" | "hours" | "minutes" | "seconds" | "milliseconds";
const fieldReflect: { [key in flexKey]: Function[] } = {
date: [Date.prototype.setDate, Date.prototype.getDate],
month: [Date.prototype.setMonth, Date.prototype.getMonth],
year: [Date.prototype.setFullYear, Date.prototype.getFullYear],
hours: [Date.prototype.setHours, Date.prototype.getHours],
minutes: [Date.prototype.setMinutes, Date.prototype.getMinutes],
seconds: [Date.prototype.setSeconds, Date.prototype.getSeconds],
milliseconds: [Date.prototype.setMilliseconds, Date.prototype.getMilliseconds],
};
export function add(from: Date, cnt: number, field: flexKey = "date") {
const temp = new Date(from.getTime());
const [setter, getter] = fieldReflect[field];
const val = getter.apply(temp);
setter.apply(temp, [val + cnt]);
return temp;
}
export function between(from: string | Date, to: string | Date = format(new Date(), masks.isoDate)) {
from = typeof from === "string" ? parse(from) : parse(format(from, masks.isoDate));
to = typeof to === "string" ? parse(to) : parse(format(to, masks.isoDate));
const val = (to.getTime() - from.getTime()) / (24 * 60 * 60 * 1000);
return (val >= 0 ? 1 : -1) * Math.floor(Math.abs(val));
}
export function* each(from: string | Date, to: string | Date = format(new Date(), masks.isoDate)) {
if (from instanceof Date) {
from = format(from, masks.isoDate);
}
if (to instanceof Date) {
to = format(to, masks.isoDate);
}
if (from.length !== 10 || to.length !== 10) {
throw Error(`cannot match param ${from} or ${to}`);
}
let fromDate = parse(from);
const toDate = parse(to);
// console.log(format(from), format(to));
fromDate = new Date(fromDate.getTime());
while (between(fromDate, toDate) >= 0) {
yield fromDate;
fromDate = add(fromDate, 1, "date");
}
}
// Internationalization strings
const i18n = {
dayNames: [
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
],
monthNames: [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
]
};
// Some common format strings
type maskKey = "default" | "timestamp" | "shortDate" | "mediumDate" | "longDate" | "fullDate" | "shortTime"
| "mediumTime" | "longTime" | "isoDate" | "isoTime" | "isoDateTime" | "isoUtcDateTime" | string;
export const masks: { [key in maskKey]: string } = {
default: "yyyy-MM-dd HH:mm:ss",
timestamp: "yyyyMMddHHmmss",
shortDate: "M/d/yy",
mediumDate: "MMM d, yyyy",
longDate: "MMMM d, yyyy",
fullDate: "dddd, MMMM d, yyyy",
shortTime: "h:mm TT",
mediumTime: "h:mm:ss TT",
longTime: "h:mm:ss TT Z",
isoDate: "yyyy-MM-dd",
isoTime: "HH:mm:ss",
isoDateTime: "yyyy-MM-dd'T'HH:mm:ss",
isoUtcDateTime: "UTC:yyyy-MM-dd'T'HH:mm:ss'Z'",
};
const regToken = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
timezoneClip = /[^-+\dA-Z]/g;
export function format(date: Date = new Date(), mask: maskKey = "default", utc = false) {
mask = String(masks[mask] || mask || masks.default);
// Allow setting the utc argument via the mask
if (mask.slice(0, 4) === "UTC:") {
mask = mask.slice(4);
utc = true;
}
const d = (utc ? Date.prototype.getUTCDate : Date.prototype.getDate).apply(date),
D = (utc ? Date.prototype.getUTCDay : Date.prototype.getDay).apply(date),
M = (utc ? Date.prototype.getUTCMonth : Date.prototype.getMonth).apply(date),
y = (utc ? Date.prototype.getUTCFullYear : Date.prototype.getFullYear).apply(date),
H = (utc ? Date.prototype.getUTCHours : Date.prototype.getHours).apply(date),
m = (utc ? Date.prototype.getUTCMinutes : Date.prototype.getMinutes).apply(date),
s = (utc ? Date.prototype.getUTCSeconds : Date.prototype.getSeconds).apply(date),
L = (utc ? Date.prototype.getUTCMilliseconds : Date.prototype.getMilliseconds).apply(date),
o = utc ? 0 : date.getTimezoneOffset();
const flags: { [key in string]: any } = {
d: d,
dd: pad(d),
ddd: i18n.dayNames[D],
dddd: i18n.dayNames[D + 7],
M: M + 1,
MM: pad(M + 1),
MMM: i18n.monthNames[M],
MMMM: i18n.monthNames[M + 12],
yy: String(y).slice(2),
yyyy: y,
h: H % 12 || 12,
hh: pad(H % 12 || 12),
H: H,
HH: pad(H),
m: m,
mm: pad(m),
s: s,
ss: pad(s),
l: pad(L, 3),
L: pad(L > 99 ? Math.round(L / 10) : L),
t: H < 12 ? "a" : "p",
tt: H < 12 ? "am" : "pm",
T: H < 12 ? "A" : "P",
TT: H < 12 ? "AM" : "PM",
Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 !== 10 ? 1 : 0) * d % 10]
};
return mask.replace(regToken, function ($0) {
return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
});
}
function pad(value: any, length?: number) {
if (!length) length = 2;
value = String(value);
while (value.length < length) {
value = "0" + value;
}
return value;
}
}
import * as crypto from "crypto";
export namespace EncryptUtil {
export function md5(source: string): string {
return crypto.createHash("md5")
.update(source)
.digest("hex");
}
const AES_KEY = new Int8Array([ 107, -127, -3, -23, 35, 124, -118, -52, -100, 22, -68, -8, 32, 75, -31, 56 ]);
const AES_algorithm = "aes-128-ecb";
export function encryptAES(data: string) {
const cipherChunks = [];
const cipher = crypto.createCipheriv(AES_algorithm, AES_KEY, "");
cipher.setAutoPadding(true);
cipherChunks.push(cipher.update(data, "utf8", "hex"));
cipherChunks.push(cipher.final("hex"));
return cipherChunks.join("");
}
export function decryptAES(data: string) {
const cipherChunks = [];
const cipher = crypto.createDecipheriv(AES_algorithm, AES_KEY, "");
cipher.setAutoPadding(true);
cipherChunks.push(cipher.update(data, "hex", "utf8"));
cipherChunks.push(cipher.final("utf8"));
return cipherChunks.join("");
}
}
import { DateUtil } from "./date-util";
import { StringUtil } from "./string-util";
export namespace GenUtil {
export function serial(prefix = "No.") {
const timestamp = DateUtil.format(new Date(), DateUtil.masks.timestamp); // 拼接时间戳
const ran = StringUtil.fullLeft(Math.floor(Math.random() * 1000).toString()); // 1000以内的随机数
return [
prefix, // 前缀
timestamp,
StringUtil.fullLeft(ran, 3, "0"),
].join("");
}
}
export * from "./date-util";
export * from "./encrypt-util";
export * from "./gen-util";
export * from "./math-util";
export * from "./number-util";
export * from "./object-util";
export * from "./promise-util";
export * from "./string-util";
export * from "./var-util";
export * from "./zip16-util";
import { VarUtil } from "./var-util";
export namespace MathUtil {
export function randomNumBoth(min: number, max: number) {
const range = max - min;
const rand = Math.random();
return min + Math.round(rand * range);
}
// 自己实现toFixed
export function toFixed(num: number, n: number) {
const sign = num < 0 ? -1 : 1;
const s = String(Math.pow(10, n) * Math.abs(num) + 0.5);
return sign * parseInt(s, 10) / Math.pow(10, n);
}
type nos = number | string;
// 计算小数位数
export function decimalPlaces(num: nos) {
return String(num).replace(/^(\+|-|)\d*(.|)/, "").length;
}
// 两个浮点数求和
export function add(num1: nos, num2: nos) {
const r1 = decimalPlaces(num1);
const r2 = decimalPlaces(num2);
const m = Math.pow(10, Math.max(r1, r2));
// console.log(r1, r2, m);
return Math.round(Number(num1) * m + Number(num2) * m) / m;
}
// 两个浮点数相减
export function sub(num1: nos, num2: nos) {
const r1 = decimalPlaces(num1);
const r2 = decimalPlaces(num2);
const n = Math.max(r1, r2);
const m = Math.pow(10, n);
return toFixed((Math.round(Number(num1) * m - Number(num2) * m) / m), n);
}
// 两个浮点数相乘
export function mul(num1: nos, num2: nos) {
const m = decimalPlaces(num1) + decimalPlaces(num2);
return Number(String(num1).replace(".", "")) *
Number(String(num2).replace(".", "")) /
Math.pow(10, m);
}
// 两个浮点数相除
export function div(num1: nos, num2: nos) {
const t1 = decimalPlaces(num1);
const t2 = decimalPlaces(num2);
const r1 = Number(String(num1).replace(".", ""));
const r2 = Number(String(num2).replace(".", ""));
return (r1 / r2) * Math.pow(10, t2 - t1);
}
// @ts-ignore
type ctk = ctk[] | string | number | "+" | "-" | "*" | "/";
/**
* 模拟clojure的方式计算
* 调用方式 calc(['+', 1, 2, 3, 4, ['*', 2, 3]])
*/
export function calc(condition: ctk[]) {
if (condition.length < 3) {
throw Error(`${condition} is not valid`);
}
const result: ctk[] = condition.map(exp => VarUtil.isArray(exp) ? calc(exp) : exp);
const operator = result.shift();
const operate = getOperateFn(operator);
// console.log(JSON.stringify([operator, ...result]));
// console.log();
while (result.length > 1) {
result.splice(0, 2, operate.apply(void 0, result.slice(0, 2)));
}
return Number(result[0]);
}
function getOperateFn(operator: string) {
switch (operator) {
case "+":
return MathUtil.add;
case "-":
return MathUtil.sub;
case "*":
return MathUtil.mul;
case "/":
return MathUtil.div;
default:
throw Error(`${operator} is not an operator`);
}
}
/**
* 四则运算表达式求值 支持括号,+,-,*,/,但使用字符串时不支持负数
* 传入数组时,可以通过多级数组控制计算优先级
* 但是更推荐使用calc (可以省略重复的运算符)
*/
export function exp(condition: ctk[]) {
let expression;
try {
if (Array.isArray(condition)) {
expression = condition.join(" ");
condition = condition.map(eyt => Array.isArray(eyt) ? exp(eyt) : eyt);
// console.log(exp);
return Number(evalRpn(stack2Rpn(condition)));
} else {
expression = condition;
return Number(evalRpn(dal2Rpn(condition)));
}
} catch (e) {
e.message = `${e.message} by exp:{${expression}}`;
throw e;
}
}
function expand(input: ctk[]) {
const result = [].concat(input);
const splice = Array.prototype.splice;
for (let idx = 0; idx < result.length;) {
const itm = result[idx];
if (!Array.isArray(itm)) {
idx++;
continue;
}
itm.unshift("(");
itm.push(")");
splice.apply(result, [idx, 1].concat(itm));
}
return result;
}
function getPriority(value: string) {
switch (value) {
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
default:
return 0;
}
}
function priority(o1: string, o2: string) {
return getPriority(o1) <= getPriority(o2);
}
function dal2Rpn(exp: string) {
return stack2Rpn(exp.match(/(\d+\.\d+|\d+)|[\+\-\*\/\(\)]/g));
}
const operateToken = ["+", "-", "*", "/", "(", ")"];
function stack2Rpn(inputStack: ctk[]) {
let cur;
const outputStack = [];
const outputQueue = [];
// console.log('step one');
while (inputStack.length > 0) {
cur = String(inputStack.shift());
if (!operateToken.includes(cur)) {
outputQueue.push(cur);
continue;
}
if (cur === "(") {
outputStack.push(cur);
continue;
}
if (cur === ")") {
let po = outputStack.pop();
while (po !== "(" && outputStack.length > 0) {
outputQueue.push(po);
po = outputStack.pop();
}
if (po !== "(") {
throw Error("error: unmatched ()");
}
continue;
}
while (priority(cur, outputStack[outputStack.length - 1]) && outputStack.length > 0) {
outputQueue.push(outputStack.pop());
}
outputStack.push(cur);
}
// console.log('step two');
if (outputStack.length > 0) {
const finalToken = outputStack[outputStack.length - 1];
if (finalToken === ")" || finalToken === "(") {
throw Error("error: unmatched ()");
}
while (outputStack.length > 0) {
outputQueue.push(outputStack.pop());
}
}
// console.log('step three');
return outputQueue;
}
function getResult(fir: nos, sec: nos, cur: nos) {
let result;
switch (cur) {
case "+":
result = MathUtil.add(fir, sec); break;
case "-":
result = MathUtil.sub(fir, sec); break;
case "*":
result = MathUtil.mul(fir, sec); break;
case "/":
result = MathUtil.div(fir, sec); break;
default:
throw Error("invalid expression");
}
// console.log(`${fir} ${cur} ${sec} = ${result}`);
return result;
}
function evalRpn(rpnQueue: string[]) {
const outputStack = [];
// console.log(rpnQueue);
while (rpnQueue.length > 0) {
const cur = rpnQueue.shift();
if (!operateToken.includes(cur)) {
outputStack.push(cur);
continue;
}
if (outputStack.length < 2) {
throw Error("invalid stack length");
}
const sec = String(outputStack.pop());
const fir = String(outputStack.pop());
outputStack.push(getResult(fir, sec, cur));
}
if (outputStack.length !== 1) {
throw Error("invalid expression");
} else {
return outputStack[0];
}
}
}
export namespace NumberUtil {
export function fmt_Rp(num: number) {
if (num && !isNaN(num)) {
return String(num).replace(/(?=(?!^)(?:\d{3})+(?:\.|$))(\d{3}(\.\d+$)?)/g, ",$1")
.replace(/[.,]/g, t => t === "," ? "." : ",");
}
return num;
}
export function parse_Rp(str: string) {
if (str) {
const rpz = str.replace(/[.,]/g, t => t === "," ? "." : "");
if (/^\d*(\.\d*)?$/.test(rpz)) {
return Number(rpz);
}
}
return str;
}
}
import { VarUtil } from "./var-util";
export namespace ObjectUtil {
/** 为obj添加一个可记忆属性(只有第一次取值时,才会根据getter取值) */
export function reserveField<T>(obj: any, field: string, getter: () => T) {
Object.defineProperty(obj, field, {
get: reserveGetter(getter),
});
}
/** 第一次调用以后,始终返回相同的值 */
export function reserveGetter<T>(val: () => T): () => T {
let lazied = false;
let lazyVal: T;
return function () {
if (!lazied) {
lazied = true;
lazyVal = val();
}
return lazyVal;
};
}
type IConstructor = NumberConstructor | StringConstructor | BooleanConstructor | ObjectConstructor;
/** 直接当做一个对象来处理 */
export function reserveObject<T>(getter: () => T, _constructor: IConstructor): T {
// @ts-ignore
class ReserveObject<T> extends _constructor {
private readonly getter: () => T;
constructor(getter: () => T) {
super();
this.getter = reserveGetter(() => _constructor(getter()));
}
toPrimitive() { return this.getter(); }
valueOf() { return this.getter(); }
toString() {return String(this.getter()); }
}
// @ts-ignore
return new ReserveObject(getter);
}
export function* arrayIterator<T>(arg: T[]) {
for (const item of (arg as T[])) {
yield item;
}
}
export function* objectIterator<T>(arg: T) {
for (const key of <(keyof T)[]>(Object.keys(arg).sort())) {
yield {key, value: arg[key]};
}
}
export function* createIterator(arg: any) {
if (VarUtil.isArray(arg)) {
for (const item of arg) {
yield item;
}
} else if (VarUtil.isObject(arg)) {
for (const key of Object.keys(arg).sort()) {
yield {key, value: arg[key]};
}
} else {
yield arg;
}
}
}
import { VarUtil } from "./var-util";
export namespace PromiseUtil {
export function promising(from: any, name: string): (<T>(...args: any[]) => Promise<T>) {
const fn = (arguments.length === 2 && VarUtil.isFunction(from)) ? from : from[name];
return function (...args: any[]) {
return new Promise(function (resolve, reject) {
fn.apply(from, [...args, function (err: Error, data: any) {
if (err) return reject(err);
resolve(data);
}]);
});
};
}
/**
* 多个任务依次执行(顺序同步,无迸发)
*/
export async function series<T>(tasks: (() => Promise<T>)[]): Promise<T[]> {
const results: T[] = [];
const copy = [...tasks];
while (copy.length) {
const task = copy.shift();
const result = await task();
results.push(result);
}
return results;
}
/**
* 在多个worker中同步执行任务,多worker之间为迸发,单worker内为同步
* 可以保证证某个任务一定在前一个任务开始后才开始(但是不保证某个任务一定在前一个任务结束后才开始)
*/
export async function queue<T>(count: number, tasks: (() => Promise<T>)[]): Promise<T[]> {
const results: T[] = [];
const copy = [...tasks];
const units: any[] = [];
while (units.length < count) units.push(void 0);
const len = tasks.length;
await Promise.all(units.map(async () => {
while (copy.length) {
const idx = len - copy.length;
const task = copy.shift();
results[idx] = await task();
}
}));
return results;
}
}
export namespace StringUtil {
export function fullLeft(str: string, len = 3, char = "0") {
if (str.length < len) {
str = char + str;
}
return str;
}
export function fullRight(str: string, len = 3, char = "0") {
if (str.length < len) {
str = str + char;
}
return str;
}
export function equalIgnoreCase(str1: string, str2: string) {
return String(str1).toLowerCase() === String(str2).toLowerCase();
}
}
export namespace VarUtil {
export function is(variable: any, type: string): boolean {
return typeOf(variable) === type;
}
export function typeOf(variable: any): string {
const tag: string = Object.prototype.toString.call(variable);
const match: string = tag.match(/(?<=\s)[\W\w]*(?=])/)[0];
return match.toLowerCase();
}
export function isNumber(variable: any): boolean {
return is(variable, "number");
}
export function isString(variable: any): boolean {
return is(variable, "string");
}
export function isBoolean(variable: any): boolean {
return is(variable, "boolean");
}
export function isObject(variable: any): boolean {
return is(variable, "object");
}
export function isArray(variable: any): boolean {
if (Array.isArray) {
return Array.isArray(variable);
}
return is(variable, "array");
}
export function isFunction(variable: any): boolean {
return is(variable, "function");
}
export function isSymbol(variable: any): boolean {
return is(variable, "symbol");
}
export function isRegExp(variable: any): boolean {
return is(variable, "regexp");
}
export function isDate(variable: any): boolean {
return is(variable, "date");
}
export function isError(variable: any): boolean {
return is(variable, "error");
}
export function isUndefined(variable: any): boolean {
return is(variable, "undefined");
}
export function isNull(variable: any): boolean {
return is(variable, "null");
}
}
export namespace Zip16Util {
// 可以修改zip字符串,zip字符串要求长度是64位,不重复的字符串,超出64位的部分不会影响编码结果
const zip = "!*(-_).0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const hex = "0123456789abcdef";
//
const separator = "~";
function full(str: string, length: number) {
while (str.length < length) {
str = "0" + str;
}
return str;
}
const des6: string[] = [];
for (let a = 0; a < 64; a++) {
des6.push(full(a.toString(2), 6));
}
const des4: string[] = [];
for (let a = 0; a < 16; a++) {
des4.push(full(a.toString(2), 4));
}
function binary(str: string, des: string[], dict: string) {
return str.split("")
.map(c => des[dict.indexOf(c)])
.join("")
.replace(/^0*/, "");
}
function source(bin: string, len: number, des: string[], dict: string) {
let position = bin.length;
const temp = [];
while (position > 0) {
temp.push(full(bin.slice(Math.max(position - len, 0), position), len));
position = position - len;
}
return temp.reverse()
.map(b => dict[des.indexOf(b)])
.join("");
}
/**
* 对0~f进制的字符串按照进制转换规则执行编码
*/
export function encode(str: string) {
const bin = binary(str, des4, hex);
return [
source(bin, 6, des6, zip),
source(str.length.toString(2), 6, des6, zip)
].join(separator);
}
/**
* 对压缩结果执行解码
*/
export function decode(str: string) {
const [dist, sign] = str.split(separator);
const bin = binary(dist, des6, zip);
const len = binary(sign, des6, zip);
return full(
source(bin, 4, des4, hex),
parseInt(len, 2)
);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册