001: package org.bouncycastle.asn1;
002:
003: import java.io.IOException;
004:
005: /**
006: * DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
007: */
008: public class DERNumericString extends ASN1Object implements DERString {
009: String string;
010:
011: /**
012: * return a Numeric string from the passed in object
013: *
014: * @exception IllegalArgumentException if the object cannot be converted.
015: */
016: public static DERNumericString getInstance(Object obj) {
017: if (obj == null || obj instanceof DERNumericString) {
018: return (DERNumericString) obj;
019: }
020:
021: if (obj instanceof ASN1OctetString) {
022: return new DERNumericString(((ASN1OctetString) obj)
023: .getOctets());
024: }
025:
026: if (obj instanceof ASN1TaggedObject) {
027: return getInstance(((ASN1TaggedObject) obj).getObject());
028: }
029:
030: throw new IllegalArgumentException(
031: "illegal object in getInstance: "
032: + obj.getClass().getName());
033: }
034:
035: /**
036: * return an Numeric String from a tagged object.
037: *
038: * @param obj the tagged object holding the object we want
039: * @param explicit true if the object is meant to be explicitly
040: * tagged false otherwise.
041: * @exception IllegalArgumentException if the tagged object cannot
042: * be converted.
043: */
044: public static DERNumericString getInstance(ASN1TaggedObject obj,
045: boolean explicit) {
046: return getInstance(obj.getObject());
047: }
048:
049: /**
050: * basic constructor - with bytes.
051: */
052: public DERNumericString(byte[] string) {
053: char[] cs = new char[string.length];
054:
055: for (int i = 0; i != cs.length; i++) {
056: cs[i] = (char) (string[i] & 0xff);
057: }
058:
059: this .string = new String(cs);
060: }
061:
062: /**
063: * basic constructor - without validation..
064: */
065: public DERNumericString(String string) {
066: this (string, false);
067: }
068:
069: /**
070: * Constructor with optional validation.
071: *
072: * @param string the base string to wrap.
073: * @param validate whether or not to check the string.
074: * @throws IllegalArgumentException if validate is true and the string
075: * contains characters that should not be in a NumericString.
076: */
077: public DERNumericString(String string, boolean validate) {
078: if (validate && !isNumericString(string)) {
079: throw new IllegalArgumentException(
080: "string contains illegal characters");
081: }
082:
083: this .string = string;
084: }
085:
086: public String getString() {
087: return string;
088: }
089:
090: public String toString() {
091: return string;
092: }
093:
094: public byte[] getOctets() {
095: char[] cs = string.toCharArray();
096: byte[] bs = new byte[cs.length];
097:
098: for (int i = 0; i != cs.length; i++) {
099: bs[i] = (byte) cs[i];
100: }
101:
102: return bs;
103: }
104:
105: void encode(DEROutputStream out) throws IOException {
106: out.writeEncoded(NUMERIC_STRING, this .getOctets());
107: }
108:
109: public int hashCode() {
110: return this .getString().hashCode();
111: }
112:
113: boolean asn1Equals(DERObject o) {
114: if (!(o instanceof DERNumericString)) {
115: return false;
116: }
117:
118: DERNumericString s = (DERNumericString) o;
119:
120: return this .getString().equals(s.getString());
121: }
122:
123: /**
124: * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
125: *
126: * @param str string to validate.
127: * @return true if numeric, fale otherwise.
128: */
129: public static boolean isNumericString(String str) {
130: for (int i = str.length() - 1; i >= 0; i--) {
131: char ch = str.charAt(i);
132:
133: if (ch > 0x007f) {
134: return false;
135: }
136:
137: if (('0' <= ch && ch <= '9') || ch == ' ') {
138: continue;
139: }
140:
141: return false;
142: }
143:
144: return true;
145: }
146: }
|