forked from MrXujiang/xijs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: 修改(prettier/prettier) 报错 * docs: update README.md * docs: update no-console 报 error * docs: update no-constant-condition 报 error * docs: update no-constant-condition 报 error * docs: 添加 IPv6 正则表达式 * docs: 添加 IPv6 正则表达式 * docs: delete no-console * docs: dele ipv6 * feat: 添加数据脱敏 * feat: 添加数据脱敏 * feat: 添加数据脱敏 * feat: 添加 双向链表
1 parent
7ca5e1f
commit e660768
Showing
8 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--- | ||
title: bothLinkedList - 双向链表 | ||
nav: | ||
title: 使用文档 | ||
path: /lib | ||
group: | ||
path: /format | ||
title: 数据结构相关 | ||
order: 2 | ||
--- | ||
|
||
## bothLinkedList | ||
|
||
> 双向链表 | ||
> | ||
> bothLinkedList.insertHead(param): param 是 需要插入的元素,插入到元素链表尾部 <br> | ||
> bothLinkedList.insertIndex(param, index): param 是 需要插入的元素,index: 需要插入的位置 <br> | ||
> bothLinkedList.getHead(): 从头开始遍历链表 <br> | ||
> bothLinkedList.getTail(): 从尾开始遍历链表 <br> | ||
> bothLinkedList.getData(index): index: 通过索引获取元素值 <br> | ||
> bothLinkedList.getSize(): 获取链表长度 <br> | ||
> bothLinkedList.deleteFrom(index): index 通过索引删除元素节点 <br> | ||
> bothLinkedList.deleteData(param): index 通过元素值删除元素节点 <br> | ||
> | ||
> 返回值:Node 类型: | ||
> | ||
> { data: 1, next: undefined, prev: undefined } | ||
Demo: | ||
|
||
```tsx | pure | ||
import { BothLinkedList } from 'xijs'; | ||
|
||
let bothLinkedList = new BothLinkedList() | ||
bothLinkedList.insertHead(1); | ||
bothLinkedList.insertHead(2); | ||
// bothLinkedList.insertHead(3) | ||
console.log(bothLinkedList.getHead()) | ||
bothLinkedList.deleteFrom(1) | ||
bothLinkedList.deleteData(1) | ||
console.log(bothLinkedList.getHead()) | ||
// console.log(bothLinkedList.getTail()) | ||
// console.log(bothLinkedList.getData(3)) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/** | ||
* 定义链表结构 | ||
* @param data | ||
* @param next | ||
* @constructor | ||
*/ | ||
class Node<T> { | ||
data: T; | ||
next: Node<T> | undefined; | ||
prev: Node<T> | undefined; | ||
|
||
constructor(data: T) { | ||
this.data = data; | ||
} | ||
} | ||
class BothLinkedList<T> { | ||
private head: Node<T> | undefined; | ||
private tail: Node<T> | undefined; | ||
private size = 0; | ||
|
||
/** | ||
* 插入元素 采用尾插法 | ||
* @param data | ||
*/ | ||
insertHead(data: T): void { | ||
const node = new Node(data); | ||
if (this.size === 0) { | ||
this.head = node; | ||
this.tail = node; | ||
} else { | ||
node.prev = this.tail; | ||
this.tail!.next = node; | ||
this.tail = node; | ||
} | ||
this.size++; | ||
} | ||
|
||
/** | ||
* 根据索引插入元素 | ||
* @param data | ||
* @param index | ||
*/ | ||
insertIndex(data: T, index: number): void { | ||
if (index < 0 || index > this.size) { | ||
throw new Error("要插入的索引已经超过了链表的最大长度"); | ||
} | ||
const node = new Node(data); | ||
/** | ||
* 如果链表为空,直接插入 | ||
*/ | ||
if (this.head === null) { | ||
this.head = node; | ||
this.tail = node; | ||
} | ||
/** | ||
* 如果 index === 0 则插入的位置是头 | ||
* 如果 index === this.size 则插入的位置是尾 | ||
*/ | ||
if (index === 0) { | ||
node.next = this.head; | ||
this.head!.prev = node; | ||
this.head = node; | ||
} else if (index === this.size) { | ||
node.prev = this.tail; | ||
this.tail!.next = node; | ||
this.tail = node; | ||
} else { | ||
let current = this.head!; | ||
for (let i = 0; i < index - 1; i++) { | ||
current = current.next!; | ||
} | ||
node.prev = current; | ||
node.next = current.next; | ||
current.next!.prev = node; | ||
current.next = node; | ||
} | ||
this.size++; | ||
} | ||
|
||
/** | ||
* 删除元素(根据元素值进行删除) | ||
*/ | ||
deleteData(data: string): void { | ||
if (this.size === 0) { | ||
throw Error("双向链表为空,不能删除") | ||
} | ||
let current = this.head!; | ||
while (current) { | ||
if (current.data === data) { | ||
if (this.size === 1) { | ||
this.head = undefined; | ||
this.tail = undefined; | ||
} else if (current === this.head) { | ||
this.head = this.head!.next; | ||
this.head!.prev = undefined; | ||
} else if (current === this.tail) { | ||
this.tail = this.tail!.prev; | ||
this.tail!.next = undefined; | ||
} else { | ||
current.prev!.next = current.next; | ||
current.next!.prev = current.prev; | ||
} | ||
|
||
this.size--; | ||
return; | ||
} | ||
current = current!.next!; | ||
} | ||
} | ||
|
||
/** | ||
* 根据元素索引删除 | ||
* @param index | ||
*/ | ||
deleteFrom(index: number): void { | ||
if (index < 0 || index >= this.size) { | ||
throw new Error("Index out of range"); | ||
} | ||
if (this.size === 1) { | ||
this.head = undefined; | ||
this.tail = undefined; | ||
} else if (index === 0) { | ||
this.head = this.head!.next!; | ||
this.head!.prev = undefined; | ||
} else if (index === this.size - 1) { | ||
this.tail = this.tail!.prev; | ||
this.tail!.next = undefined; | ||
} else { | ||
let current = this.head!; | ||
for (let i = 0; i < index; i++) { | ||
current = current.next!; | ||
} | ||
current.prev!.next = current.next; | ||
current.next!.prev = current.prev; | ||
} | ||
this.size--; | ||
} | ||
|
||
/** | ||
* 正向遍历 | ||
*/ | ||
getHead(): Node<T> | undefined { | ||
return this.head; | ||
} | ||
|
||
/** | ||
* 反向遍历 | ||
*/ | ||
getTail(): Node<T> | undefined { | ||
return this.tail; | ||
} | ||
|
||
/** | ||
* 获取链表长度 | ||
*/ | ||
getSize(): number { | ||
return this.size; | ||
} | ||
|
||
/** | ||
* 更具索引,获取元素值 | ||
* @param index | ||
*/ | ||
getData(index: number): T | undefined { | ||
if (index < 0 || index >= this.size) { | ||
throw Error("要查找的索引已经超过了链表的最大长度") | ||
} | ||
let current = this.head; | ||
for (let i = 0; i < index; i++) { | ||
current = current!.next; | ||
} | ||
return current!.data; | ||
} | ||
} | ||
export default BothLinkedList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
--- | ||
title: dataDesensitization - 数据脱敏 | ||
nav: | ||
title: 使用文档 | ||
path: /lib | ||
group: | ||
path: /judge | ||
title: 常用判断函数 | ||
order: 12 | ||
--- | ||
|
||
## dataDesensitization | ||
|
||
> 数据脱敏 | ||
> | ||
> regex(param1, param2, param3m param4): param1 是 需要脱敏的类型,param2:需要脱敏的数据, param3: 自定义脱敏时 脱敏开始位置, param4: 自定义脱敏的位数 | ||
> | ||
> idCard: 身份证 脱敏<br> | ||
> phone: 手机号 脱敏<br> | ||
> fixPhone: 手机号 脱敏<br> | ||
> email: 邮箱 脱敏<br> | ||
> username: 姓名 脱敏<br> | ||
> custom: 自定义 脱敏<br> | ||
> | ||
> 返回值为 string 值,脱敏完的字符串 | ||
Demo: | ||
|
||
```tsx | pure | ||
|
||
// 按需引入 | ||
import { dataDesensitization } from 'xijs'; | ||
|
||
console.log('610222188709080909: ', dataDesensitization('idCard', '610222188709080909')); | ||
console.log('18396781187: ', dataDesensitization('phone', '18396781187')); | ||
console.log('18396781187: ', dataDesensitization('custom', '18396781187', 1, 8)); | ||
console.log('深证市龙岗区五和: ', dataDesensitization('address', '深证市龙岗区五和')); | ||
console.log('1832291@qq.com: ', dataDesensitization('email', '1832291@qq.com')); | ||
console.log('小小西: ', dataDesensitization('username', '小小西')); | ||
console.log('小西: ', dataDesensitization('username', '小西')); | ||
console.log('小西小西: ', dataDesensitization('username', '小西小西')); | ||
console.log('012-1823293: ', dataDesensitization('fixPhone', '012-1823293')); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { repeat } from "../index"; | ||
|
||
const dataDesensitizationMap = { | ||
idCard: (data: string): string => { | ||
return data.replace(/(\d{2})\d{14}(\w{2})/, "$1" + repeat("*", 14) + "$2"); | ||
}, | ||
phone: (data: string): string => { | ||
return data.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2"); | ||
}, | ||
bankCard: (data: string): string => { | ||
return data.replace(/(\d{4})\d{10}(\w{4})/, "$1" + repeat("*", 10) + "$2"); | ||
}, | ||
address: (data: string): string => { | ||
return data.replace(/(\S{2})\S*/, "$1" + repeat("*", data.length - 2)); | ||
}, | ||
custom: (data: string, begin: number, desensitization: number): string => { | ||
const end = data.length - begin - desensitization; | ||
const regexp = RegExp(`(\\d{` + begin + `})\\d{` + desensitization + `}(\\w{` + end + `})`); | ||
return data.replace(regexp, "$1" + repeat("*", desensitization) + "$2"); | ||
}, | ||
fixPhone: (data: string): string => { | ||
return data.replace(/(\w{3}-)\w*/, "$1" + repeat("*", data.length - 4)); | ||
}, | ||
email: (data: string): string => { | ||
return data.replace(/(\w?)(\w+)(\w)(@\w+\.[a-z]+(\.[a-z]+)?)/, '$1****$3$4') | ||
}, | ||
username: (data: string): string => { | ||
return data.replace(/(\S)(\S*)/, "$1" + repeat("*", data.length - 1)) | ||
} | ||
}; | ||
|
||
type DataDesensitization = "idCard" | "bankCard" | "phone" | "address" | "custom" | "fixPhone" | "email" | "username"; | ||
const dataDesensitization = (des: DataDesensitization, data: string, begin = 0, desensitization = 0) => { | ||
if (des === "custom") { | ||
return dataDesensitizationMap["custom"](data, begin, desensitization); | ||
} else if (dataDesensitizationMap[des]) { | ||
return dataDesensitizationMap[des](data); | ||
} else { | ||
throw Error("请输入正确的脱敏类型"); | ||
} | ||
return; | ||
}; | ||
|
||
|
||
export default dataDesensitization; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { BothLinkedList } from '../src/index'; | ||
describe('双向链表相关测试', () => { | ||
test('双向链表', () => { | ||
const bothLinkedList = new BothLinkedList(); | ||
const insertRes = { data: 1, next: undefined, prev: undefined } | ||
bothLinkedList.insertHead(1); | ||
expect(bothLinkedList.getHead()).toEqual(insertRes) | ||
bothLinkedList.insertHead(2); | ||
bothLinkedList.deleteData(2); | ||
bothLinkedList.deleteData(1); | ||
expect(bothLinkedList.getHead()).toEqual(undefined) | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
|
||
import { dataDesensitization, repeat } from '../src/index'; | ||
describe('数据脱敏相关测试', () => { | ||
test('数据脱敏', () => { | ||
expect(dataDesensitization('idCard', '610222188709080909')).toEqual('61**************09') | ||
expect(dataDesensitization('phone', '18396781187')).toEqual('183****1187') | ||
expect(dataDesensitization('custom', '18396781187', 1, 8)).toEqual('1********87') | ||
expect(dataDesensitization('address', '深证市龙岗区五和')).toEqual('深证******') | ||
expect(dataDesensitization('email', '1832291@qq.com')).toEqual('1****1@qq.com') | ||
expect(dataDesensitization('username', '小小西')).toEqual('小**') | ||
expect(dataDesensitization('fixPhone', '012-1823293')).toEqual('012-*******') | ||
}); | ||
}); |