ARM ASSEMBLY ONLY take a file of strings (Which may be binary data) and convert
ID: 646489 • Letter: A
Question
ARM ASSEMBLY ONLY
take a file of strings (Which may be binary data) and convert those string to a Base64 encoding.
The encoding scheme to use is the same as that used in rfc1421.
Base64 encoding is a process by which three binary characters are encoded and replaced with 4 text characters. Text characters include A-Z, a-z, 0-9,+,/ (these are all easily printable characters and don't pose any problems to communication software, such as email.) We also use the '=' to represent "padded" characters.
So... Three characters is three bytes, three bytes is 24 bits. But you are going to divide these 24 bits into 4 sets of 6 bits. 2^6 = 64, hence base "64" encoding.
The subsequence "ABC" in a string would have the ASCII values 65 (01000001), 66 (01000010), and 67 (01000011) for a total 24 bit sequence of 010000010100001001000011. Chunking this into 6-bits chunks yields... 010000 010100 001001 000011. As 4 numbers this is 16, 20, 9, and 3. in RFC1421 this equates to the replacement sequence "QUJD"
If the number of letters in a string is not divisible for 3 pad it with = signs.
So take a file of multiple strings, Encode each line in RFC1421 Base64 encoding and output that line to a new file.
THe input file is called "input.txt" the output file shall be named "output64.txt"
Each input line will be less than 1024 characters
Each line may include binary data but will not include carriage return (' ') or newline (' ').
Each line will be terminated by the two character end of line sequence (" ")
Explanation / Answer
void ToBase64( BYTE* pSrc, char* pszOutBuf, int len ) { char* chr_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; __asm{ mov ecx, len mov esi, pSrc //;bytes from source mov edi, chr_table push ebp mov ebp, pszOutBuf src_byteLoop: xor eax, eax //;read 3 bytes mov ah, byte ptr[esi] mov al, byte ptr[esi+1] shl eax, 16 mov ah, byte ptr[esi+2] //;manipulate in edx bitset1 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;manipulate in edx bitset2 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;manipulate in edx bitset3 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;manipulate in edx bitset4 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;done these bytes add esi, 3 sub ecx, 3 cmp ecx, 3 jge src_byteLoop //;still got src bytes xor eax, eax //;set to zero (pad count) cmp ecx, 0 jz finished //;need to pad out some extra bytes //;read in 3 bytes regardless of junk data following pSrc - already zero from above) mov ah, byte ptr[esi] mov al, byte ptr[esi+1] shl eax, 16 mov ah, byte ptr[esi+2] sub ecx, 3 //;bytes just read neg ecx //;+ve inverse mov edx, ecx //;save how many bytes need padding //;as per the RFC, any padded bytes should be 0s mov esi, 0xFFFFFF lea ecx, dword ptr[ecx*8+8] //;calculate bitmask to shift shl esi, cl and eax, esi //;mask out the junk bytes mov ecx, edx //;restore pad count //;manipulate in edx byte 1 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;manipulate in edx byte 2 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;manipulate in edx byte 3 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf //;manipulate in edx byte 3 mov edx, eax shl eax, 6 //;done first 6 bits shr edx, 26 mov bl, byte ptr [edi+edx] //;put char in buffer mov byte ptr[ebp], bl inc ebp //;next buf mov eax, ecx //;'return' pad count finished: test eax, eax jz end //;some bytes were padding, put them as = sub ebp, eax //;move ptr back for num bytes to pad padChars: mov byte ptr[ebp], 0x3d //;= inc ebp dec eax jnz padChars end: pop ebp } }