1 package org.bouncycastle.asn1;
2 
3 import java.io.IOException;
4 import java.math.BigInteger;
5 
6 import org.bouncycastle.util.Arrays;
7 
8 /**
9  * Class representing the ASN.1 INTEGER type.
10  */
11 public class ASN1Integer
12     extends ASN1Primitive
13 {
14     private final byte[] bytes;
15 
16     /**
17      * return an integer from the passed in object
18      *
19      * @param obj an ASN1Integer or an object that can be converted into one.
20      * @throws IllegalArgumentException if the object cannot be converted.
21      * @return an ASN1Integer instance.
22      */
getInstance( Object obj)23     public static ASN1Integer getInstance(
24         Object obj)
25     {
26         if (obj == null || obj instanceof ASN1Integer)
27         {
28             return (ASN1Integer)obj;
29         }
30 
31         if (obj instanceof byte[])
32         {
33             try
34             {
35                 return (ASN1Integer)fromByteArray((byte[])obj);
36             }
37             catch (Exception e)
38             {
39                 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
40             }
41         }
42 
43         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
44     }
45 
46     /**
47      * return an Integer from a tagged object.
48      *
49      * @param obj      the tagged object holding the object we want
50      * @param explicit true if the object is meant to be explicitly
51      *                 tagged false otherwise.
52      * @throws IllegalArgumentException if the tagged object cannot
53      * be converted.
54      * @return an ASN1Integer instance.
55      */
getInstance( ASN1TaggedObject obj, boolean explicit)56     public static ASN1Integer getInstance(
57         ASN1TaggedObject obj,
58         boolean explicit)
59     {
60         ASN1Primitive o = obj.getObject();
61 
62         if (explicit || o instanceof ASN1Integer)
63         {
64             return getInstance(o);
65         }
66         else
67         {
68             return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets());
69         }
70     }
71 
ASN1Integer( long value)72     public ASN1Integer(
73         long value)
74     {
75         bytes = BigInteger.valueOf(value).toByteArray();
76     }
77 
ASN1Integer( BigInteger value)78     public ASN1Integer(
79         BigInteger value)
80     {
81         bytes = value.toByteArray();
82     }
83 
ASN1Integer( byte[] bytes)84     public ASN1Integer(
85         byte[] bytes)
86     {
87         this(bytes, true);
88     }
89 
ASN1Integer(byte[] bytes, boolean clone)90     ASN1Integer(byte[] bytes, boolean clone)
91     {
92         this.bytes = (clone) ? Arrays.clone(bytes) : bytes;
93     }
94 
getValue()95     public BigInteger getValue()
96     {
97         return new BigInteger(bytes);
98     }
99 
100     /**
101      * in some cases positive values get crammed into a space,
102      * that's not quite big enough...
103      * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
104      */
getPositiveValue()105     public BigInteger getPositiveValue()
106     {
107         return new BigInteger(1, bytes);
108     }
109 
isConstructed()110     boolean isConstructed()
111     {
112         return false;
113     }
114 
encodedLength()115     int encodedLength()
116     {
117         return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
118     }
119 
encode( ASN1OutputStream out)120     void encode(
121         ASN1OutputStream out)
122         throws IOException
123     {
124         out.writeEncoded(BERTags.INTEGER, bytes);
125     }
126 
hashCode()127     public int hashCode()
128     {
129         int value = 0;
130 
131         for (int i = 0; i != bytes.length; i++)
132         {
133             value ^= (bytes[i] & 0xff) << (i % 4);
134         }
135 
136         return value;
137     }
138 
asn1Equals( ASN1Primitive o)139     boolean asn1Equals(
140         ASN1Primitive o)
141     {
142         if (!(o instanceof ASN1Integer))
143         {
144             return false;
145         }
146 
147         ASN1Integer other = (ASN1Integer)o;
148 
149         return Arrays.areEqual(bytes, other.bytes);
150     }
151 
toString()152     public String toString()
153     {
154         return getValue().toString();
155     }
156 
157 }
158