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
021 package org.apache.directory.shared.ldap.util;
022
023
024 /**
025 * decoding of base32 characters to raw bytes.
026 *
027 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
028 * @version $Revision: 664290 $
029 */
030 public class Base32
031 {
032 private static byte[] CHARS = new byte[]{
033 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
034 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
035 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
036 'Y', 'Z', '2', '3', '4', '5', '6', '7' };
037
038
039 public static String encode( String str )
040 {
041 if ( StringTools.isEmpty( str ) )
042 {
043 return "";
044 }
045
046 byte[] data = StringTools.getBytesUtf8( str );
047 int dataLength = data.length;
048 int newLength = ( ( dataLength << 3 ) / 5 ) + ( ( dataLength % 5 ) == 0 ? 0 : 1 );
049 newLength += ( ( newLength % 8 == 0 ) ? 0 : 8 - newLength % 8 );
050 byte[] out = new byte[newLength];
051
052 int roundLength = (dataLength/5) * 5;
053 int posOut = 0;
054 int posIn = 0;
055
056 if ( roundLength != 0 )
057 {
058 for ( posIn = 0; posIn < roundLength; posIn += 5 )
059 {
060 byte b0 = data[posIn];
061 byte b1 = data[posIn+1];
062 byte b2 = data[posIn+2];
063 byte b3 = data[posIn+3];
064 byte b4 = data[posIn+4];
065
066 out[posOut++] = CHARS[( b0 & 0xF8) >> 3];
067 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ];
068 out[posOut++] = CHARS[( b1 & 0x3E) >> 1];
069 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 ) | ( ( b2 & 0xF0 ) >> 4 ) ];
070 out[posOut++] = CHARS[( ( b2 & 0x0F) << 1 ) | ( ( b3 & 0x80 ) >> 7 ) ];
071 out[posOut++] = CHARS[( b3 & 0x7C) >> 2];
072 out[posOut++] = CHARS[( ( b3 & 0x03) << 3 ) | ( ( b4 & 0x70 ) >> 5 )];
073 out[posOut++] = CHARS[b4 & 0x1F];
074 }
075 }
076
077 int remaining = dataLength - roundLength;
078
079 switch ( remaining )
080 {
081 case 1 :
082 byte b0 = data[posIn++];
083
084 out[posOut++] = CHARS[( b0 & 0xF8) >> 3];
085 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 )];
086 out[posOut++] = '=';
087 out[posOut++] = '=';
088 out[posOut++] = '=';
089 out[posOut++] = '=';
090 out[posOut++] = '=';
091 out[posOut++] = '=';
092 break;
093
094 case 2 :
095 b0 = data[posIn++];
096 byte b1 = data[posIn++];
097
098 out[posOut++] = CHARS[( b0 & 0xF8) >> 3];
099 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ];
100 out[posOut++] = CHARS[( b1 & 0x3E) >> 1];
101 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 )];
102 out[posOut++] = '=';
103 out[posOut++] = '=';
104 out[posOut++] = '=';
105 out[posOut++] = '=';
106 break;
107
108 case 3 :
109 b0 = data[posIn++];
110 b1 = data[posIn++];
111 byte b2 = data[posIn++];
112
113 out[posOut++] = CHARS[( b0 & 0xF8) >> 3];
114 out[posOut++] = CHARS[( ( b0 & 0x07) << 2 ) | ( ( b1 & 0xC0 ) >> 6 ) ];
115 out[posOut++] = CHARS[( b1 & 0x3E) >> 1];
116 out[posOut++] = CHARS[( ( b1 & 0x01) << 4 ) | ( ( b2 & 0xF0 ) >> 4 ) ];
117 out[posOut++] = CHARS[( ( b2 & 0x0F) << 1 ) ];
118 out[posOut++] = '=';
119 out[posOut++] = '=';
120 out[posOut++] = '=';
121 break;
122
123 case 4 :
124 b0 = data[posIn++];
125 b1 = data[posIn++];
126 b2 = data[posIn++];
127 byte b3 = 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 ) | ( ( b3 & 0x80 ) >> 7 ) ];
134 out[posOut++] = CHARS[( b3 & 0x7C) >> 2];
135 out[posOut++] = CHARS[( ( b3 & 0x03) << 3 ) ];
136 out[posOut++] = '=';
137 break;
138 }
139
140 return StringTools.utf8ToString( out );
141 }
142 }