1// basecode.cpp - written and placed in the public domain by Wei Dai 2 3#include "pch.h" 4 5#ifndef CRYPTOPP_IMPORTS 6 7#include "basecode.h" 8#include "fltrimpl.h" 9#include <ctype.h> 10 11NAMESPACE_BEGIN(CryptoPP) 12 13void BaseN_Encoder::IsolatedInitialize(const NameValuePairs ¶meters) 14{ 15 parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet); 16 17 parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar); 18 if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) 19 throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive"); 20 21 byte padding; 22 bool pad; 23 if (parameters.GetValue(Name::PaddingByte(), padding)) 24 pad = parameters.GetValueWithDefault(Name::Pad(), true); 25 else 26 pad = false; 27 m_padding = pad ? padding : -1; 28 29 m_bytePos = m_bitPos = 0; 30 31 int i = 8; 32 while (i%m_bitsPerChar != 0) 33 i += 8; 34 m_outputBlockSize = i/m_bitsPerChar; 35 36 m_outBuf.New(m_outputBlockSize); 37} 38 39size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) 40{ 41 FILTER_BEGIN; 42 while (m_inputPosition < length) 43 { 44 if (m_bytePos == 0) 45 memset(m_outBuf, 0, m_outputBlockSize); 46 47 { 48 unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8; 49 while (true) 50 { 51 assert(m_bitPos < m_bitsPerChar); 52 unsigned int bitsLeftInTarget = m_bitsPerChar-m_bitPos; 53 m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget); 54 if (bitsLeftInSource >= bitsLeftInTarget) 55 { 56 m_bitPos = 0; 57 ++m_bytePos; 58 bitsLeftInSource -= bitsLeftInTarget; 59 if (bitsLeftInSource == 0) 60 break; 61 b <<= bitsLeftInTarget; 62 b &= 0xff; 63 } 64 else 65 { 66 m_bitPos += bitsLeftInSource; 67 break; 68 } 69 } 70 } 71 72 assert(m_bytePos <= m_outputBlockSize); 73 if (m_bytePos == m_outputBlockSize) 74 { 75 int i; 76 for (i=0; i<m_bytePos; i++) 77 { 78 assert(m_outBuf[i] < (1 << m_bitsPerChar)); 79 m_outBuf[i] = m_alphabet[m_outBuf[i]]; 80 } 81 FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0); 82 83 m_bytePos = m_bitPos = 0; 84 } 85 } 86 if (messageEnd) 87 { 88 if (m_bitPos > 0) 89 ++m_bytePos; 90 91 int i; 92 for (i=0; i<m_bytePos; i++) 93 m_outBuf[i] = m_alphabet[m_outBuf[i]]; 94 95 if (m_padding != -1 && m_bytePos > 0) 96 { 97 memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos); 98 m_bytePos = m_outputBlockSize; 99 } 100 FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); 101 m_bytePos = m_bitPos = 0; 102 } 103 FILTER_END_NO_MESSAGE_END; 104} 105 106void BaseN_Decoder::IsolatedInitialize(const NameValuePairs ¶meters) 107{ 108 parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup); 109 110 parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar); 111 if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) 112 throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive"); 113 114 m_bytePos = m_bitPos = 0; 115 116 int i = m_bitsPerChar; 117 while (i%8 != 0) 118 i += m_bitsPerChar; 119 m_outputBlockSize = i/8; 120 121 m_outBuf.New(m_outputBlockSize); 122} 123 124size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) 125{ 126 FILTER_BEGIN; 127 while (m_inputPosition < length) 128 { 129 unsigned int value; 130 value = m_lookup[begin[m_inputPosition++]]; 131 if (value >= 256) 132 continue; 133 134 if (m_bytePos == 0 && m_bitPos == 0) 135 memset(m_outBuf, 0, m_outputBlockSize); 136 137 { 138 int newBitPos = m_bitPos + m_bitsPerChar; 139 if (newBitPos <= 8) 140 m_outBuf[m_bytePos] |= value << (8-newBitPos); 141 else 142 { 143 m_outBuf[m_bytePos] |= value >> (newBitPos-8); 144 m_outBuf[m_bytePos+1] |= value << (16-newBitPos); 145 } 146 147 m_bitPos = newBitPos; 148 while (m_bitPos >= 8) 149 { 150 m_bitPos -= 8; 151 ++m_bytePos; 152 } 153 } 154 155 if (m_bytePos == m_outputBlockSize) 156 { 157 FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0); 158 m_bytePos = m_bitPos = 0; 159 } 160 } 161 if (messageEnd) 162 { 163 FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); 164 m_bytePos = m_bitPos = 0; 165 } 166 FILTER_END_NO_MESSAGE_END; 167} 168 169void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive) 170{ 171 std::fill(lookup, lookup+256, -1); 172 173 for (unsigned int i=0; i<base; i++) 174 { 175 if (caseInsensitive && isalpha(alphabet[i])) 176 { 177 assert(lookup[toupper(alphabet[i])] == -1); 178 lookup[toupper(alphabet[i])] = i; 179 assert(lookup[tolower(alphabet[i])] == -1); 180 lookup[tolower(alphabet[i])] = i; 181 } 182 else 183 { 184 assert(lookup[alphabet[i]] == -1); 185 lookup[alphabet[i]] = i; 186 } 187 } 188} 189 190void Grouper::IsolatedInitialize(const NameValuePairs ¶meters) 191{ 192 m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0); 193 ConstByteArrayParameter separator, terminator; 194 if (m_groupSize) 195 parameters.GetRequiredParameter("Grouper", Name::Separator(), separator); 196 else 197 parameters.GetValue(Name::Separator(), separator); 198 parameters.GetValue(Name::Terminator(), terminator); 199 200 m_separator.Assign(separator.begin(), separator.size()); 201 m_terminator.Assign(terminator.begin(), terminator.size()); 202 m_counter = 0; 203} 204 205size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) 206{ 207 FILTER_BEGIN; 208 if (m_groupSize) 209 { 210 while (m_inputPosition < length) 211 { 212 if (m_counter == m_groupSize) 213 { 214 FILTER_OUTPUT(1, m_separator, m_separator.size(), 0); 215 m_counter = 0; 216 } 217 218 size_t len; 219 FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter), 220 begin+m_inputPosition, len, 0); 221 m_inputPosition += len; 222 m_counter += len; 223 } 224 } 225 else 226 FILTER_OUTPUT(3, begin, length, 0); 227 228 if (messageEnd) 229 { 230 FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd); 231 m_counter = 0; 232 } 233 FILTER_END_NO_MESSAGE_END 234} 235 236NAMESPACE_END 237 238#endif 239