Skip to content

Commit fdd0300

Browse files
committed
feat: b64toURLSafe() convert base64 string to URL-safe string
https://en.wikipedia.org/wiki/Base64#URL_applications
1 parent 65306d3 commit fdd0300

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from './lib/index'
33
export * from './lib/model'
44
export { ErrorMsg } from './lib/config'
55
export {
6+
b64toURLSafe,
67
isArrayBuffer,
78
isUint8Array,
89
testB64,

src/lib/helper.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,18 @@ export function isUint8Array(buffer: any): buffer is Uint8Array {
144144
? true
145145
: false
146146
}
147+
148+
149+
/**
150+
* Convert base64 string to URL-safe string.
151+
* Replace "+" to "-" and "/" to "_", and Remove "="
152+
*
153+
* @see https://en.wikipedia.org/wiki/Base64#URL_applications
154+
*/
155+
export function b64toURLSafe(base64: string): string {
156+
validateB64(base64)
157+
const pos = base64.indexOf('=')
158+
return pos > 0
159+
? base64.slice(0, pos).replace(/\+/g, '-').replace(/\//g, '_')
160+
: base64.replace(/\+/g, '-').replace(/\//g, '_')
161+
}

test/30_helper.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313

1414
import { ErrorMsg } from '../src/index'
1515
import {
16+
b64toURLSafe,
1617
isArrayBuffer,
1718
isUint8Array,
1819
parseDecodeInputBase64,
@@ -334,4 +335,27 @@ describe(filename, () => {
334335
})
335336

336337

338+
describe('base64ToURLSafe() works', () => {
339+
it('with valid input', () => {
340+
inputURLSafe.forEach(([str, b64, b64url]) => {
341+
const ret = b64toURLSafe(b64)
342+
const b64node = Buffer.from(str).toString('base64')
343+
assert(ret === b64url, `"${ret}" !== "${b64url}"`)
344+
assert(b64 === b64node, `${b64} !== ${b64node}`)
345+
})
346+
})
347+
348+
it('with invalid input', () => {
349+
inputURLSafe2.forEach(b64 => {
350+
try {
351+
b64toURLSafe(b64)
352+
assert(false, 'Should throw error, but NOT')
353+
}
354+
catch (ex) {
355+
assert(true)
356+
}
357+
})
358+
})
359+
})
360+
337361
})

test/config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ export const inputURLSafe = [
155155
]
156156

157157
export const inputURLSafe2 = [
158-
'A', 'QQ', '=QQ', 'Q=Q',
158+
'A',
159+
'QQ',
160+
'=QQ',
161+
'Q=Q',
162+
'AABB\nAABB',
159163
]
160164

161165
export const inputBase64CharsInvalid = [
@@ -166,6 +170,7 @@ export const inputBase64CharsInvalid = [
166170
'=QQ==',
167171
'=QQ=',
168172
'=QQ',
173+
'AABB\nAABB',
169174
]
170175
export const inputBase64Invalid = [
171176
0,
@@ -180,6 +185,7 @@ export const inputBase64Invalid = [
180185
'=QQ==',
181186
'=QQ=',
182187
'=QQ',
188+
'AABB\nAABB',
183189
]
184190

185191
export const inputBase64URLCharsInvalid = [
@@ -191,9 +197,11 @@ export const inputBase64URLCharsInvalid = [
191197
'=QQ==',
192198
'=QQ',
193199
'QQ+/',
200+
'AABB\nAABB',
194201
]
195202
export const inputBase64URLInvalid = [
196203
0,
197204
'',
198205
'Q',
206+
'AABB\nAABB',
199207
]

0 commit comments

Comments
 (0)