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 }