Skip to content

Commit

Permalink
feat(utils): 新增 rot13
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jan 15, 2021
1 parent cab7da0 commit 6450d00
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 13 deletions.
16 changes: 3 additions & 13 deletions src/utils/ListWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { base64UrlDecode, base64UrlEncode } from './base64'
import { isPlainObject, mapValues, range, shuffle } from 'lodash-uni'
import { rot13 } from './rot13'

export type RawList<TItem = any> = TItem[]

Expand All @@ -13,27 +14,16 @@ export interface WrappedList<TItem = any> {
* 列表打包器。
*/
export class ListWrapper {
private static rot13(str: string) {
return str.replace(/[a-z]/gi, char => {
return String.fromCharCode(
char.charCodeAt(0) + (char.toLowerCase() < 'n' ? 13 : -13),
)
})
}

private static encodeValueIndexes(indexes: number[]) {
return ListWrapper.rot13(
return rot13(
base64UrlEncode(
`${Math.random().toString(36).slice(2)}.${indexes.join('.')}`,
),
)
}

private static decodeValueIndexes(value: string) {
return base64UrlDecode(ListWrapper.rot13(value))
.split('.')
.slice(1)
.map(Number)
return base64UrlDecode(rot13(value)).split('.').slice(1).map(Number)
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export * from './placeKitten'
export * from './pMap'
export * from './readFile'
export * from './RichUrl'
export * from './rot13'
export * from './run'
export * from './swap'
export * from './traverse'
Expand Down
32 changes: 32 additions & 0 deletions src/utils/rot13.perf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { rot13 } from './rot13'
import { runBenchmark } from '../dev'

function rot13Arr(str: string) {
const input = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
const output = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
const index = (x: string) => input.indexOf(x)
const translate = (x: string) => (index(x) > -1 ? output[index(x)] : x)
return str.split('').map(translate).join('')
}

function rot13Re(str: string) {
return str.replace(/[a-z]/gi, char => {
return String.fromCharCode(
char.charCodeAt(0) + (char.toLowerCase() < 'n' ? 13 : -13),
)
})
}

const str = `ROT13 is its own inverse. Meaning, to undo ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding.`

runBenchmark({
['rot13!fastest']() {
rot13(str)
},
['rot13Arr']() {
rot13Arr(str)
},
['rot13Re']() {
rot13Re(str)
},
})
12 changes: 12 additions & 0 deletions src/utils/rot13.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { rot13 } from './rot13'

describe('rot13', () => {
test('表现正常', () => {
expect(rot13('hello world')).toBe('uryyb jbeyq')
expect(rot13('uryyb jbeyq')).toBe('hello world')
expect(rot13('foo-bar')).toBe('sbb-one')
expect(rot13('foo123bar')).toBe('sbb123one')
expect(rot13('foo!@bar')).toBe('sbb!@one')
expect(rot13('sbb!@one')).toBe('foo!@bar')
})
})
25 changes: 25 additions & 0 deletions src/utils/rot13.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const input = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
const output = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'.split('')
const lookup = input.reduce<Record<string, string>>((m, k, i) => {
m[k] = output[i]
return m
}, Object.create(null))

/**
* 回转 13 位替换式密码。
*
* @param str 原文
* @see https://zh.wikipedia.org/wiki/ROT13
* @example
* ```typescript
* rot13('hello world') // => 'uryyb jbeyq'
* ```
*/
export function rot13(str: string): string {
let res = ''
for (let i = 0, len = str.length; i < len; i++) {
const char = str.charAt(i)
res += lookup[char] || char
}
return res
}

0 comments on commit 6450d00

Please sign in to comment.