MCPcopy Create free account
hub / github.com/cryptii/cryptii / performTranslate

Method performTranslate

src/Encoder/AffineCipher.js:93–151  ·  view source on GitHub ↗

* Performs encode or decode on given content. * @param {Chain} content * @param {boolean} isEncode True for encoding, false for decoding * @return {number[]|string|Uint8Array|Chain} Resulting content

(content, isEncode)

Source from the content-addressed store, hash-verified

91 * @return {number[]|string|Uint8Array|Chain} Resulting content
92 */
93 performTranslate (content, isEncode) {
94 const { a, b, caseStrategy, includeForeignChars } = this.getSettingValues()
95
96 // Prepare alphabet(s) depending on chosen case strategy
97 let alphabet = this.getSettingValue('alphabet')
98 let uppercaseAlphabet
99 if (caseStrategy !== 'strict') {
100 alphabet = alphabet.toLowerCase()
101 uppercaseAlphabet = alphabet.toUpperCase()
102 }
103
104 const m = alphabet.getLength()
105 const n = content.getLength()
106 const result = new Array(n).fill(0)
107
108 let codePoint, uppercase, i, c, x, y
109 let j = 0
110
111 for (i = 0; i < n; i++) {
112 codePoint = content.getCodePointAt(i)
113
114 // Match alphabet character
115 x = alphabet.indexOfCodePoint(codePoint)
116 uppercase = false
117
118 // Match uppercase alphabet character (depending on case strategy)
119 if (x === -1 && caseStrategy !== 'strict') {
120 x = uppercaseAlphabet.indexOfCodePoint(codePoint)
121 uppercase = true
122 }
123
124 if (x === -1) {
125 // Character not in alphabet
126 if (includeForeignChars) {
127 // Take over character unchanged
128 result[j++] = codePoint
129 }
130 } else {
131 // Translate character index through linear function
132 if (isEncode) {
133 // E(x) = (ax + b) mod m
134 y = MathUtil.mod(a * x + b, m)
135 } else {
136 // D(x) = (a^-1(x - b)) mod m
137 c = MathUtil.xgcd(a, m)[0]
138 y = MathUtil.mod(c * (x - b), m)
139 }
140
141 // Put index back into a character following the case strategy
142 if (caseStrategy === 'maintain' && uppercase) {
143 result[j++] = uppercaseAlphabet.getCodePointAt(y)
144 } else {
145 result[j++] = alphabet.getCodePointAt(y)
146 }
147 }
148 }
149
150 return result.slice(0, j)

Callers

nothing calls this directly

Calls 9

getSettingValuesMethod · 0.80
getSettingValueMethod · 0.80
toLowerCaseMethod · 0.80
toUpperCaseMethod · 0.80
getCodePointAtMethod · 0.80
indexOfCodePointMethod · 0.80
modMethod · 0.80
xgcdMethod · 0.80
getLengthMethod · 0.45

Tested by

no test coverage detected