📄 base64.cpp
字号:
/************************************************** Base64 Encoder/Decoder Source File ** (C) 1999-2002 The Botan Project **************************************************/#include <botan/base64.h>namespace Botan {/************************************************** Base64_Encoder Constructor **************************************************/Base64_Encoder::Base64_Encoder(bool breaks, u32bit length) : LINEBREAKS(breaks), LINELENGTH(length), in_buffer(48), out_buffer(4) { counter = position = 0; if(LINEBREAKS && (LINELENGTH == 0)) throw Invalid_Argument("Base64_Encoder: Output lines cannot be zero " "characters long"); }/************************************************** Base64 Encoding Operation **************************************************/void Base64_Encoder::encode(const byte in[3], byte out[4]) { static const byte BIN_TO_BASE64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; out[0] = BIN_TO_BASE64[((in[0] & 0xFC) >> 2)]; out[1] = BIN_TO_BASE64[((in[0] & 0x03) << 4) | (in[1] >> 4)]; out[2] = BIN_TO_BASE64[((in[1] & 0x0F) << 2) | (in[2] >> 6)]; out[3] = BIN_TO_BASE64[((in[2] & 0x3F) )]; }/************************************************** Encode and send a block **************************************************/void Base64_Encoder::encode_and_send(const byte block[], u32bit length) { for(u32bit j = 0; j != length; j += 3) { encode(block + j, out_buffer); do_output(out_buffer, 4); } }/************************************************** Handle the output **************************************************/void Base64_Encoder::do_output(const byte input[], u32bit length) { if(LINEBREAKS) { u32bit remaining = length, offset = 0; while(remaining) { u32bit sent = std::min(LINELENGTH - counter, remaining); send(input + offset, sent); counter += sent; remaining -= sent; offset += sent; if(counter == LINELENGTH) { send('\n'); counter = 0; } } } else send(input, length); }/************************************************** Convert some data into Base64 **************************************************/void Base64_Encoder::write(const byte input[], u32bit length) { in_buffer.copy(position, input, length); if(position + length >= in_buffer.size()) { encode_and_send(in_buffer, in_buffer.size()); input += (in_buffer.size() - position); length -= (in_buffer.size() - position); while(length >= in_buffer.size()) { encode_and_send(input, in_buffer.size()); input += in_buffer.size(); length -= in_buffer.size(); } in_buffer.copy(input, length); position = 0; } position += length; }/************************************************** Flush buffers **************************************************/void Base64_Encoder::end_msg() { u32bit start_of_last_block = 3 * (position / 3), left_over = position % 3; encode_and_send(in_buffer, start_of_last_block); if(left_over) { SecureBuffer<byte, 3> remainder(in_buffer + start_of_last_block, left_over); encode(remainder, out_buffer); u32bit empty_bits = 8 * (3 - left_over), index = 4 - 1; while(empty_bits >= 8) { out_buffer[index--] = '='; empty_bits -= 6; } do_output(out_buffer, 4); } if(counter && LINEBREAKS) send('\n'); counter = position = 0; }/************************************************** Base64_Decoder Constructor **************************************************/Base64_Decoder::Base64_Decoder() : in_buffer(48), out_buffer(3) { position = 0; }/************************************************** Base64 Decoding Operation **************************************************/void Base64_Decoder::decode(const byte in[4], byte out[3]) { out[0] = (byte)((BASE64_TO_BIN[in[0]] << 2) | (BASE64_TO_BIN[in[1]] >> 4)); out[1] = (byte)((BASE64_TO_BIN[in[1]] << 4) | (BASE64_TO_BIN[in[2]] >> 2)); out[2] = (byte)((BASE64_TO_BIN[in[2]] << 6) | (BASE64_TO_BIN[in[3]])); }/************************************************** Decode and send a block **************************************************/void Base64_Decoder::decode_and_send(const byte block[], u32bit length) { for(u32bit j = 0; j != length; j += 4) { decode(block + j, out_buffer); send(out_buffer, 3); } }/************************************************** Convert some data from Base64 **************************************************/void Base64_Decoder::write(const byte input[], u32bit length) { for(u32bit j = 0; j != length; j++) { if(is_valid(input[j])) in_buffer[position++] = input[j]; if(position == in_buffer.size()) { decode_and_send(in_buffer, in_buffer.size()); position = 0; } } }/************************************************** Flush buffers **************************************************/void Base64_Decoder::end_msg() { if(position != 0) { u32bit start_of_last_block = 4 * (position / 4), left_over = position % 4; decode_and_send(in_buffer, start_of_last_block); if(left_over) { SecureBuffer<byte, 4> remainder(in_buffer + start_of_last_block, left_over); decode(remainder, out_buffer); send(out_buffer, ((left_over == 1) ? (1) : (left_over - 1))); } } position = 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -