001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: Radix64Codec.java,v $ 023 Revision 1.5 2004/05/05 22:47:37 markl 024 comment block updates 025 026 Revision 1.4 2003/01/19 09:34:27 markl 027 Javadoc & comment header updates. 028 029 Revision 1.3 2001/03/12 02:18:28 markl 030 Source code cleanup. 031 032 Revision 1.2 1999/01/10 03:37:18 markl 033 added GPL header & RCS tag 034 ---------------------------------------------------------------------------- 035*/ 036 037package kiwi.text; 038 039/** This class implements a codec for the Radix-64 encoding scheme. For a 040 * high-level interface, see the <i>Radix64InputStream</i> and 041 * <i>Radix64OutputStream</i> filters in <b>kiwi.io</b>. 042 * <p> 043 * This codec implements Radix-64 as defined by the <i>PGP</i> software. 044 * 045 * @see kiwi.io.Radix64InputStream 046 * @see kiwi.io.Radix64OutputStream 047 * 048 * @author Mark Lindner 049 */ 050 051public class Radix64Codec 052 { 053 private static final String radix64 054 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 055 private static final byte pad = (byte)'='; 056 057 private Radix64Codec() {} 058 059 /** Determine if a byte is a valid Radix-64 encoding character; one of the 060 * characters: '+', '/', '=', '0' - '9', 'A' - 'Z', 'a' - 'z'. 061 * 062 * @param c The byte to test. 063 * 064 * @return <code>true</code> if <code>c</code> is a Radix-64 character, 065 * <code>false</code> 066 * otherwise. 067 */ 068 069 public static final boolean isRadix64Character(byte c) 070 { 071 return((radix64.indexOf((char)c) != -1) || (c == pad)); 072 } 073 074 /** Encode up to 3 bytes of binary data as 4 bytes of printable ASCII text. 075 * 076 * @param input A 3-byte long array of input. 077 * @param len The number of bytes (1, 2, or 3) that are significant in the 078 * input. 079 * 080 * @return A 4-byte array of printable characters that represent the 081 * Radix-64 encoding of the input. The output will include padding ('=' 082 * characters) if not all 3 bytes of the input were significant. 083 */ 084 085 public static final byte[] encode(byte input[], int len) 086 { 087 byte out[] = new byte[4]; 088 089 // 3 bytes --> 4 bytes 090 // the highest order byte becomes the first radix-64 'digit' 091 092 int x = 0; 093 for(int i = 0; i < 3; i++) 094 { 095 if(i > 0) x <<= 8; 096 if(i < len) 097 x |= input[i]; 098 } 099 100 for(int i = 0; i < 4; i++) 101 { 102 out[3 - i] = (byte)(radix64.charAt(x & 0x3F)); 103 x >>>= 6; 104 } 105 106 if(len < 3) out[3] = pad; 107 if(len < 2) out[2] = pad; 108 109 return(out); 110 } 111 112 /** Decode 4 bytes of printable ASCII text into up to 3 bytes of binary data. 113 * 114 * @param input A 4-byte long array of input bytes. 115 * @param output A 3-byte long array in which up to 3 bytes of decoded 116 * output will be stored. 117 * 118 * @return The number of bytes decoded (1, 2, or 3). 119 */ 120 121 public static final int decode(byte input[], byte output[]) 122 { 123 int out = 0; 124 int len = 3; 125 126 if(input[3] == pad) len--; 127 if(input[2] == pad) len--; 128 129 for(int i = 0; i < 4; i++) 130 { 131 if(i > 0) out <<= 6; 132 out |= (byte)(radix64.indexOf((char)input[i])); 133 } 134 135 for(int i = 0; i < 3; i++) 136 { 137 if(i > 0) out >>>= 8; 138 output[2 - i] = (byte)(out & 0xFF); 139 } 140 141 return(len); 142 } 143 144 } 145 146/* end of source file */