@@ -15,14 +15,6 @@ const isNode =
15
15
globalThis . process . release &&
16
16
globalThis . process . release . name ;
17
17
18
- function browserUtf8ToBase64 ( data : string ) {
19
- return btoa ( unescape ( encodeURIComponent ( data ) ) ) ;
20
- }
21
-
22
- function browserBase64ToUtf8 ( data : string ) {
23
- return decodeURIComponent ( escape ( atob ( data ) ) ) ;
24
- }
25
-
26
18
function nodeUtf8ToBase64 ( data : string ) {
27
19
return Buffer . from ( data , "utf-8" ) . toString ( "base64" ) ;
28
20
}
@@ -31,5 +23,35 @@ function nodeBase64ToUtf8(data: string) {
31
23
return Buffer . from ( data , "base64" ) . toString ( "utf-8" ) ;
32
24
}
33
25
26
+ // browserUtf8ToBase64 & browserBase64ToUtf8
27
+ // (c) Brandon Rylow - CC BY-SA 4.0
28
+ // https://stackoverflow.com/a/30106551/206879
29
+ function browserUtf8ToBase64 ( data : string ) {
30
+ // first we use encodeURIComponent to get percent-encoded UTF-8,
31
+ // then we convert the percent encodings into raw bytes which
32
+ // can be fed into btoa.
33
+ return btoa (
34
+ encodeURIComponent ( data ) . replace (
35
+ / % ( [ 0 - 9 A - F ] { 2 } ) / g,
36
+ function toSolidBytes ( _match , p1 ) {
37
+ // @ts -expect-error - we know what we are doing here
38
+ return String . fromCharCode ( "0x" + p1 ) ;
39
+ }
40
+ )
41
+ ) ;
42
+ }
43
+
44
+ function browserBase64ToUtf8 ( data : string ) {
45
+ // Going backwards: from bytestream, to percent-encoding, to original string.
46
+ return decodeURIComponent (
47
+ atob ( data )
48
+ . split ( "" )
49
+ . map ( function ( c ) {
50
+ return "%" + ( "00" + c . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 2 ) ;
51
+ } )
52
+ . join ( "" )
53
+ ) ;
54
+ }
55
+
34
56
export const utf8ToBase64 = isNode ? nodeUtf8ToBase64 : browserUtf8ToBase64 ;
35
57
export const base64ToUtf8 = isNode ? nodeBase64ToUtf8 : browserBase64ToUtf8 ;
0 commit comments