001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 021package org.apache.directory.shared.util; 022 023 024/** 025 * decoding of base32 characters to raw bytes. 026 * 027 * TODO: This class isn't used, remove it? 028 * 029 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 030 */ 031public final class Base32 032{ 033 /** The available characters */ 034 private static final byte[] CHARS = new byte[]{ 035 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 036 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 037 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 038 'Y', 'Z', '2', '3', '4', '5', '6', '7' }; 039 040 041 /** 042 * Private constructor. 043 */ 044 private Base32() 045 { 046 } 047 048 049 /** 050 * Encodes a string to a Base64 encoded String. 051 * 052 * @param str the string 053 * @return the Base64 encoded string 054 */ 055 public static String encode( String str ) 056 { 057 if ( Strings.isEmpty(str) ) 058 { 059 return ""; 060 } 061 062 byte[] data = Strings.getBytesUtf8(str); 063 int dataLength = data.length; 064 int newLength = ( ( dataLength << 3 ) / 5 ) + ( ( dataLength % 5 ) == 0 ? 0 : 1 ); 065 newLength += ( ( newLength % 8 == 0 ) ? 0 : 8 - newLength % 8 ); 066 byte[] out = new byte[newLength]; 067 068 int roundLength = (dataLength/5) * 5; 069 int posOut = 0; 070 int posIn = 0; 071 072 if ( roundLength != 0 ) 073 { 074 for ( posIn = 0; posIn < roundLength; posIn += 5 ) 075 { 076 byte b0 = data[posIn]; 077 byte b1 = data[posIn+1]; 078 byte b2 = data[posIn+2]; 079 byte b3 = data[posIn+3]; 080 byte b4 = data[posIn+4]; 081 082 out[posOut++] = CHARS[( b0 & 0xF8) >> 3]; 083 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ]; 084 out[posOut++] = CHARS[( b1 & 0x3E) >> 1]; 085 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 ) | ( ( b2 & 0xF0 ) >> 4 ) ]; 086 out[posOut++] = CHARS[( ( b2 & 0x0F) << 1 ) | ( ( b3 & 0x80 ) >> 7 ) ]; 087 out[posOut++] = CHARS[( b3 & 0x7C) >> 2]; 088 out[posOut++] = CHARS[( ( b3 & 0x03) << 3 ) | ( ( b4 & 0x70 ) >> 5 )]; 089 out[posOut++] = CHARS[b4 & 0x1F]; 090 } 091 } 092 093 int remaining = dataLength - roundLength; 094 095 switch ( remaining ) 096 { 097 case 1 : 098 byte b0 = data[posIn++]; 099 100 out[posOut++] = CHARS[( b0 & 0xF8) >> 3]; 101 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 )]; 102 out[posOut++] = '='; 103 out[posOut++] = '='; 104 out[posOut++] = '='; 105 out[posOut++] = '='; 106 out[posOut++] = '='; 107 out[posOut++] = '='; 108 break; 109 110 case 2 : 111 b0 = data[posIn++]; 112 byte b1 = data[posIn++]; 113 114 out[posOut++] = CHARS[( b0 & 0xF8) >> 3]; 115 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ]; 116 out[posOut++] = CHARS[( b1 & 0x3E) >> 1]; 117 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 )]; 118 out[posOut++] = '='; 119 out[posOut++] = '='; 120 out[posOut++] = '='; 121 out[posOut++] = '='; 122 break; 123 124 case 3 : 125 b0 = data[posIn++]; 126 b1 = data[posIn++]; 127 byte b2 = data[posIn++]; 128 129 out[posOut++] = CHARS[( b0 & 0xF8) >> 3]; 130 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ]; 131 out[posOut++] = CHARS[( b1 & 0x3E) >> 1]; 132 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 ) | ( ( b2 & 0xF0 ) >> 4 ) ]; 133 out[posOut++] = CHARS[( ( b2 & 0x0F) << 1 ) ]; 134 out[posOut++] = '='; 135 out[posOut++] = '='; 136 out[posOut++] = '='; 137 break; 138 139 case 4 : 140 b0 = data[posIn++]; 141 b1 = data[posIn++]; 142 b2 = data[posIn++]; 143 byte b3 = data[posIn++]; 144 145 out[posOut++] = CHARS[( b0 & 0xF8) >> 3]; 146 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ]; 147 out[posOut++] = CHARS[( b1 & 0x3E) >> 1]; 148 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 ) | ( ( b2 & 0xF0 ) >> 4 ) ]; 149 out[posOut++] = CHARS[( ( b2 & 0x0F) << 1 ) | ( ( b3 & 0x80 ) >> 7 ) ]; 150 out[posOut++] = CHARS[( b3 & 0x7C) >> 2]; 151 out[posOut++] = CHARS[( ( b3 & 0x03) << 3 ) ]; 152 out[posOut++] = '='; 153 break; 154 } 155 156 return Strings.utf8ToString(out); 157 } 158}