-
Notifications
You must be signed in to change notification settings - Fork 87
Expand file tree
/
Copy pathrhAPI.js
More file actions
139 lines (129 loc) · 3.83 KB
/
Copy pathrhAPI.js
File metadata and controls
139 lines (129 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
export class RammerheadAPI {
constructor(server, signal, password) {
this.server = server
this.signal = signal
this.password = password
}
async get(url) {
if (this.password) {
// really cheap way of adding a query parameter
if (url.includes("?")) {
url += "&pwd=" + this.password
} else {
url += "?pwd=" + this.password
}
}
try {
const request = await fetch(new URL(url, this.server), {
signal: this.signal
})
if (request.status === 200) {
return await request.text()
} else {
throw new Error(
`unexpected server response to not match "200". Server says "${await request.text()}"`
)
}
} catch (err) {
console.error(err)
throw new Error("Cannot communicate with the server")
}
}
async needPassword() {
return (await this.get("needpassword")) === "true"
}
async newSession() {
return await this.get("newsession")
}
async editSession(id, httpProxy, enableShuffling) {
const res = await this.get(
"editsession?id=" +
encodeURIComponent(id) +
(httpProxy ? "&httpProxy=" + encodeURIComponent(httpProxy) : "") +
"&enableShuffling=" +
(enableShuffling ? "1" : "0")
)
if (res !== "Success") {
throw new Error(`unexpected response from server. received ${res}`)
}
}
async sessionExists(id) {
const res = await this.get("sessionexists?id=" + encodeURIComponent(id))
switch (res) {
case "exists":
return true
case "not found":
return false
default:
throw new Error(`unexpected response from server. received ${res}`)
}
}
async deleteSession(id) {
if (await this.sessionExists(id)) {
const res = await this.get("deletesession?id=" + id)
if (res !== "Success" && res !== "not found") {
throw new Error(`unexpected response from server. received ${res}`)
}
}
}
async shuffleDict(id) {
const res = await this.get("api/shuffleDict?id=" + encodeURIComponent(id))
return JSON.parse(res)
}
}
export class StrShuffler {
baseDictionary =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~-"
shuffledIndicator = "_rhs"
constructor(dictionary) {
dictionary ||= this.generateDictionary()
this.dictionary = dictionary
}
mod(n, m) {
return ((n % m) + m) % m
}
generateDictionary() {
let str = ""
const split = this.baseDictionary.split("")
while (split.length > 0)
str += split.splice(Math.floor(Math.random() * split.length), 1)[0]
return str
}
shuffle(str) {
if (str.startsWith(this.shuffledIndicator)) return str
let shuffledStr = ""
for (let i = 0; i < str.length; i++) {
const char = str.charAt(i)
const idx = this.baseDictionary.indexOf(char)
if (char === "%" && str.length - i >= 3) {
shuffledStr += char
shuffledStr += str.charAt(++i)
shuffledStr += str.charAt(++i)
} else if (idx === -1) shuffledStr += char
else
shuffledStr += this.dictionary.charAt(
this.mod(idx + i, this.baseDictionary.length)
)
}
return this.shuffledIndicator + shuffledStr
}
unshuffle(str) {
if (!str.startsWith(this.shuffledIndicator)) return str
str = str.slice(this.shuffledIndicator.length)
let unshuffledStr = ""
for (let i = 0; i < str.length; i++) {
const char = str.charAt(i)
const idx = this.dictionary.indexOf(char)
if (char === "%" && str.length - i >= 3) {
unshuffledStr += char
unshuffledStr += str.charAt(++i)
unshuffledStr += str.charAt(++i)
} else if (idx === -1) unshuffledStr += char
else
unshuffledStr += this.baseDictionary.charAt(
this.mod(idx - i, this.baseDictionary.length)
)
}
return unshuffledStr
}
}