1 package com.lowagie.bc.asn1; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 6 public class DERBitString 7 extends DERObject 8 implements DERString 9 { 10 private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 11 12 protected byte[] data; 13 protected int padBits; 14 15 19 static protected int getPadBits( 20 int bitString) 21 { 22 int val = 0; 23 for (int i = 3; i >= 0; i--) 24 { 25 if (i != 0) 30 { 31 if ((bitString >> (i * 8)) != 0) 32 { 33 val = (bitString >> (i * 8)) & 0xFF; 34 break; 35 } 36 } 37 else 38 { 39 if (bitString != 0) 40 { 41 val = bitString & 0xFF; 42 break; 43 } 44 } 45 } 46 47 if (val == 0) 48 { 49 return 7; 50 } 51 52 53 int bits = 1; 54 55 while (((val <<= 1) & 0xFF) != 0) 56 { 57 bits++; 58 } 59 60 return 8 - bits; 61 } 62 63 67 static protected byte[] getBytes(int bitString) 68 { 69 int bytes = 4; 70 for (int i = 3; i >= 1; i--) 71 { 72 if ((bitString & (0xFF << (i * 8))) != 0) 73 { 74 break; 75 } 76 bytes--; 77 } 78 79 byte[] result = new byte[bytes]; 80 for (int i = 0; i < bytes; i++) 81 { 82 result[i] = (byte) ((bitString >> (i * 8)) & 0xFF); 83 } 84 85 return result; 86 } 87 88 93 public static DERBitString getInstance( 94 Object obj) 95 { 96 if (obj == null || obj instanceof DERBitString) 97 { 98 return (DERBitString)obj; 99 } 100 101 if (obj instanceof ASN1OctetString) 102 { 103 byte[] bytes = ((ASN1OctetString)obj).getOctets(); 104 int padBits = bytes[0]; 105 byte[] data = new byte[bytes.length - 1]; 106 107 System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 108 109 return new DERBitString(data, padBits); 110 } 111 112 if (obj instanceof ASN1TaggedObject) 113 { 114 return getInstance(((ASN1TaggedObject)obj).getObject()); 115 } 116 117 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 118 } 119 120 129 public static DERBitString getInstance( 130 ASN1TaggedObject obj, 131 boolean explicit) 132 { 133 return getInstance(obj.getObject()); 134 } 135 136 protected DERBitString( 137 byte data, 138 int padBits) 139 { 140 this.data = new byte[1]; 141 this.data[0] = data; 142 this.padBits = padBits; 143 } 144 145 149 public DERBitString( 150 byte[] data, 151 int padBits) 152 { 153 this.data = data; 154 this.padBits = padBits; 155 } 156 157 public DERBitString( 158 byte[] data) 159 { 160 this(data, 0); 161 } 162 163 public DERBitString( 164 DEREncodable obj) 165 { 166 try 167 { 168 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 169 DEROutputStream dOut = new DEROutputStream(bOut); 170 171 dOut.writeObject(obj); 172 dOut.close(); 173 174 this.data = bOut.toByteArray(); 175 this.padBits = 0; 176 } 177 catch (IOException e) 178 { 179 throw new IllegalArgumentException("Error processing object : " + e.toString()); 180 } 181 } 182 183 public byte[] getBytes() 184 { 185 return data; 186 } 187 188 public int getPadBits() 189 { 190 return padBits; 191 } 192 193 void encode( 194 DEROutputStream out) 195 throws IOException 196 { 197 byte[] bytes = new byte[getBytes().length + 1]; 198 199 bytes[0] = (byte)getPadBits(); 200 System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1); 201 202 out.writeEncoded(BIT_STRING, bytes); 203 } 204 205 public int hashCode() 206 { 207 int value = 0; 208 209 for (int i = 0; i != data.length; i++) 210 { 211 value ^= (data[i] & 0xff) << (i % 4); 212 } 213 214 return value; 215 } 216 217 public boolean equals( 218 Object o) 219 { 220 if (o == null || !(o instanceof DERBitString)) 221 { 222 return false; 223 } 224 225 DERBitString other = (DERBitString)o; 226 227 if (data.length != other.data.length) 228 { 229 return false; 230 } 231 232 for (int i = 0; i != data.length; i++) 233 { 234 if (data[i] != other.data[i]) 235 { 236 return false; 237 } 238 } 239 240 return (padBits == other.padBits); 241 } 242 243 public String getString() 244 { 245 StringBuffer buf = new StringBuffer("#"); 246 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 247 ASN1OutputStream aOut = new ASN1OutputStream(bOut); 248 249 try 250 { 251 aOut.writeObject(this); 252 } 253 catch (IOException e) 254 { 255 throw new RuntimeException("internal error encoding BitString"); 256 } 257 258 byte[] string = bOut.toByteArray(); 259 260 for (int i = 0; i != string.length; i++) 261 { 262 buf.append(table[(string[i] >>> 4) % 0xf]); 263 buf.append(table[string[i] & 0xf]); 264 } 265 266 return buf.toString(); 267 } 268 } 269 | Popular Tags |