1 package org.bouncycastle.asn1; 2 3 import java.io.IOException; 4 5 /** 6 * DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }. 7 */ 8 public class DERNumericString 9 extends ASN1Object 10 implements DERString 11 { 12 String string; 13 14 /** 15 * return a Numeric string from the passed in object 16 * 17 * @exception IllegalArgumentException if the object cannot be converted. 18 */ 19 public static DERNumericString getInstance( 20 Object obj) 21 { 22 if (obj == null || obj instanceof DERNumericString) 23 { 24 return (DERNumericString)obj; 25 } 26 27 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 28 } 29 30 /** 31 * return an Numeric String from a tagged object. 32 * 33 * @param obj the tagged object holding the object we want 34 * @param explicit true if the object is meant to be explicitly 35 * tagged false otherwise. 36 * @exception IllegalArgumentException if the tagged object cannot 37 * be converted. 38 */ 39 public static DERNumericString getInstance( 40 ASN1TaggedObject obj, 41 boolean explicit) 42 { 43 DERObject o = obj.getObject(); 44 45 if (explicit || o instanceof DERNumericString) 46 { 47 return getInstance(o); 48 } 49 else 50 { 51 return new DERNumericString(ASN1OctetString.getInstance(o).getOctets()); 52 } 53 } 54 55 /** 56 * basic constructor - with bytes. 57 */ 58 public DERNumericString( 59 byte[] string) 60 { 61 char[] cs = new char[string.length]; 62 63 for (int i = 0; i != cs.length; i++) 64 { 65 cs[i] = (char)(string[i] & 0xff); 66 } 67 68 this.string = new String(cs); 69 } 70 71 /** 72 * basic constructor - without validation.. 73 */ 74 public DERNumericString( 75 String string) 76 { 77 this(string, false); 78 } 79 80 /** 81 * Constructor with optional validation. 82 * 83 * @param string the base string to wrap. 84 * @param validate whether or not to check the string. 85 * @throws IllegalArgumentException if validate is true and the string 86 * contains characters that should not be in a NumericString. 87 */ 88 public DERNumericString( 89 String string, 90 boolean validate) 91 { 92 if (validate && !isNumericString(string)) 93 { 94 throw new IllegalArgumentException("string contains illegal characters"); 95 } 96 97 this.string = string; 98 } 99 100 public String getString() 101 { 102 return string; 103 } 104 105 public String toString() 106 { 107 return string; 108 } 109 110 public byte[] getOctets() 111 { 112 char[] cs = string.toCharArray(); 113 byte[] bs = new byte[cs.length]; 114 115 for (int i = 0; i != cs.length; i++) 116 { 117 bs[i] = (byte)cs[i]; 118 } 119 120 return bs; 121 } 122 123 void encode( 124 DEROutputStream out) 125 throws IOException 126 { 127 out.writeEncoded(NUMERIC_STRING, this.getOctets()); 128 } 129 130 public int hashCode() 131 { 132 return this.getString().hashCode(); 133 } 134 135 boolean asn1Equals( 136 DERObject o) 137 { 138 if (!(o instanceof DERNumericString)) 139 { 140 return false; 141 } 142 143 DERNumericString s = (DERNumericString)o; 144 145 return this.getString().equals(s.getString()); 146 } 147 148 /** 149 * Return true if the string can be represented as a NumericString ('0'..'9', ' ') 150 * 151 * @param str string to validate. 152 * @return true if numeric, fale otherwise. 153 */ 154 public static boolean isNumericString( 155 String str) 156 { 157 for (int i = str.length() - 1; i >= 0; i--) 158 { 159 char ch = str.charAt(i); 160 161 if (ch > 0x007f) 162 { 163 return false; 164 } 165 166 if (('0' <= ch && ch <= '9') || ch == ' ') 167 { 168 continue; 169 } 170 171 return false; 172 } 173 174 return true; 175 } 176 } 177