Base 32 Encoding
Site Map Feedback
Up ASCIIHex Base32 Base64 MIME QuotedPrintable URL UU
When turning Binary Data into Text, the shortest text is generated using Base64 encoding.
Usually the conversion takes place because the data is being sent through some medium (like the Internet) which filters or alters some binary values.
Base32 encoded data results in text which is case insensitive. This implementation only uses the capital letters and the digits 4-9.

This means that the most significant bit of each ASCII text Byte is always zero, so the Text can be transmitted through media which only transfer 7-bit data.

It is also useful for human readable codes where someone has to type a license number in because the case doesn't matter, and ambiguous shapes can be resolved:
There is no number zero, so if the user typed a zero they were actually reading the letter Oh: O.
There is no number one, so if the user typed a one they were actually reading the letter Eye: I.
There is no number two, so if the user typed a two they were actually reading the letter Zed: Z.
So when the user has typed the string you can get the Binary Data with:
  DWORD CMyDlg::GetData() {
    CString S;
    GetDlgItemText(IDC_EDIT1, S);
    S.MakeUpper();
    S.Replace('0','O');
    S.Replace('1','I');
    S.Replace('2','Z');
    DWORD Data=Base32toDWORD(S);
  }
  static CString DWORDtoBase32(DWORD num) { // DWORD to Base32 Text String conversion:
    CString Result;
    char* ptr=Result.GetBufferSetLength(7);
    for(int shift=0; shift<7*5; shift+=5) {
      char c=(char)((num>>shift) & 31);
      *ptr++=c+(c<6 ? '4' : 'A'-6);
    }
    Result.ReleaseBuffer(7);
    return Result;
  }
  static DWORD Base32toDWORD(const char* ptr) { // Base32 Text String to DWORD conversion:
    DWORD Result=0;
    for(int shift=0; shift<7*5; shift+=5) {
      char c=*ptr++;
      if(!isBase32(c)) return 0;
      Result |= ((c<'A') ? (c-'4') : (6+(c-'A')))<<shift;
    }
    return Result;
  }
  static bool isBase32(char c) {return !((c<'4') || ((c>'9') && (c<'A')) || (c>'Z'));}
The line in Base32toDWORD:
char c=*ptr++;
could be
char c=*ptr++ & 0x3F;
which would mean that you wouldn't need the MakeUpper() earlier.
That is not done because it may be important to know if the call to Base32toDWORD failed.
Of course, if its very important to know if the data was not pure Base32, then the Base32toDWORD call should have different parameters and return false if non-Base32 characters are encountered:
bool Base32toDWORD(const char* ptr, DWORD& Result) {...}
Four binary Bytes are turned into seven text Bytes.
Here's the code:
 CString DWordToBase32(DWORD num) {
   CStringA Result;
   char* ptr=Result.GetBufferSetLength(7);
   for(int shift=0; shift<7*5; shift+=5) {
     char c=(char)((num>>shift) & 31);
     *ptr++=c+(c<6 ? '4' : 'A'-6);
   }
   Result.ReleaseBuffer(7);
   return Result;
 }
 DWORD Base32ToDWord(const char* ptr) {
   DWORD Result=0;
   for(int shift=0; shift<7*5; shift+=5) {
     char c=*ptr++;
     if(!isBase32(c)) return 0;
     Result |= ((c<'A') ? (c-'4') : (6+(c-'A')))<<shift;
   }
   return Result;
 }
 bool isBase32(char c) {return !((c<'4') || ((c>'9') && (c<'A')) || (c>'Z'));}

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.