mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-06 01:18:23 +08:00
Create algorithm for converting base64 to binary data
This commit is contained in:
47
Conversions/Base64ToArrayBuffer.js
Normal file
47
Conversions/Base64ToArrayBuffer.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// About base64: https://en.wikipedia.org/wiki/Base64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a base64 string to an array of bytes
|
||||||
|
* @param {string} b64 A base64 string
|
||||||
|
* @returns {ArrayBuffer} An ArrayBuffer representing the bytes encoded by the base64 string
|
||||||
|
*/
|
||||||
|
function base64ToBuffer (b64) {
|
||||||
|
// The base64 encoding uses the following set of characters to encode any binary data as text
|
||||||
|
const base64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
|
// Find the index of char '=' first occurrence
|
||||||
|
const paddingIdx = b64.indexOf('=')
|
||||||
|
// Remove padding chars from base64 string, if there are any
|
||||||
|
const b64NoPadding = paddingIdx !== -1 ? b64.slice(0, paddingIdx) : b64
|
||||||
|
// Calculate the length of the result buffer
|
||||||
|
const bufferLength = Math.floor((b64NoPadding.length * 6) / 8)
|
||||||
|
// Create the result buffer
|
||||||
|
const result = new ArrayBuffer(bufferLength)
|
||||||
|
// Create an instance of Uint8Array, to write to the `result` buffer
|
||||||
|
const byteView = new Uint8Array(result)
|
||||||
|
|
||||||
|
// Loop through all chars in the base64 string, in increments of 4 chars, and in increments of 3 bytes
|
||||||
|
for (let i = 0, j = 0; i < b64NoPadding.length; i += 4, j += 3) {
|
||||||
|
// Get the index of the next 4 base64 chars
|
||||||
|
const b64Char1 = base64Table.indexOf(b64NoPadding[i])
|
||||||
|
const b64Char2 = base64Table.indexOf(b64NoPadding[i + 1])
|
||||||
|
let b64Char3 = base64Table.indexOf(b64NoPadding[i + 2])
|
||||||
|
let b64Char4 = base64Table.indexOf(b64NoPadding[i + 3])
|
||||||
|
|
||||||
|
// If base64 chars 3 and 4 don't exit, then set them to 0
|
||||||
|
if (b64Char3 === -1) b64Char3 = 0
|
||||||
|
if (b64Char4 === -1) b64Char4 = 0
|
||||||
|
|
||||||
|
// Calculate the next 3 bytes
|
||||||
|
const byte1 = (b64Char1 << 2) + ((b64Char2 & 48) >> 4)
|
||||||
|
const byte2 = ((b64Char2 & 15) << 4) + ((b64Char3 & 60) >> 2)
|
||||||
|
const byte3 = ((b64Char3 & 3) << 6) + b64Char4
|
||||||
|
|
||||||
|
byteView[j] = byte1
|
||||||
|
byteView[j + 1] = byte2
|
||||||
|
byteView[j + 2] = byte3
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export { base64ToBuffer }
|
26
Conversions/test/Base64ToArrayBuffer.test.js
Normal file
26
Conversions/test/Base64ToArrayBuffer.test.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { base64ToBuffer } from '../Base64ToArrayBuffer'
|
||||||
|
import { TextDecoder } from 'util'
|
||||||
|
|
||||||
|
describe('Base64ToArrayBuffer', () => {
|
||||||
|
it('should decode "SGVsbG8sIHdvcmxkIQ==" as "Hello, world!"', () => {
|
||||||
|
const testBase64String = 'SGVsbG8sIHdvcmxkIQ=='
|
||||||
|
const buffer = base64ToBuffer(testBase64String)
|
||||||
|
const decoder = new TextDecoder()
|
||||||
|
const helloWorldString = decoder.decode(buffer)
|
||||||
|
expect(helloWorldString).toBe('Hello, world!')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should decode base64 "Nxex6kQaWg==" as binary buffer [55,23,177,234,68,26,90]', () => {
|
||||||
|
const testBase64String = 'Nxex6kQaWg=='
|
||||||
|
const buffer = base64ToBuffer(testBase64String)
|
||||||
|
const array = [...new Uint8Array(buffer)]
|
||||||
|
expect(array).toEqual([55, 23, 177, 234, 68, 26, 90])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should decode base64 "AAECAwQFBgcICQ==" as binary buffer [0,1,2,3,4,5,6,7,8,9]', () => {
|
||||||
|
const testBase64String = 'AAECAwQFBgcICQ=='
|
||||||
|
const buffer = base64ToBuffer(testBase64String)
|
||||||
|
const array = [...new Uint8Array(buffer)]
|
||||||
|
expect(array).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||||
|
})
|
||||||
|
})
|
Reference in New Issue
Block a user