Asn1IntegerConverter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / Asn1IntegerConverter.cs / 1305376 / Asn1IntegerConverter.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.IdentityModel 
{
    using System.Collections.Generic; 
    using System.Text; 

    static class Asn1IntegerConverter 
    {
        static List powersOfTwo = new List(new byte[][] { new byte[] { 1 } });
        readonly static char[] digitMap = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
 
        public static string Asn1IntegerToDecimalString(byte[] asn1)
        { 
            if (asn1 == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("asn1");
 
            if (asn1.Length == 0)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("asn1", SR.GetString(SR.LengthOfArrayToConvertMustGreaterThanZero)));

 
            List positiveDecimalDigits = new List((asn1.Length * 8) / 3);
            int absoluteBitNumber = 0; 
            byte currentByte; 

            // Since X509Certificate.GetSerialNumber return the little-endian, 
            // the most significant is at the last byte.
            for (int byteNumber = 0; byteNumber < asn1.Length - 1; byteNumber++)
            {
                currentByte = asn1[byteNumber]; 
                for (int i = 0; i < 8; i++)
                { 
                    if ((currentByte & 1) == 1) 
                    {
                        AddSecondDecimalToFirst(positiveDecimalDigits, TwoToThePowerOf(absoluteBitNumber)); 
                    }
                    absoluteBitNumber++;
                    currentByte >>= 1;
                } 
            }
 
            // Special case the most significant bit of the most significant byte as a negative value 
            currentByte = asn1[asn1.Length - 1];
            for (int i = 0; i < 7; i++) 
            {
                if ((currentByte & 1) == 1)
                {
                    AddSecondDecimalToFirst(positiveDecimalDigits, TwoToThePowerOf(absoluteBitNumber)); 
                }
                absoluteBitNumber++; 
                currentByte >>= 1; 
            }
 
            StringBuilder result = new StringBuilder(positiveDecimalDigits.Count + 1);
            List resultDigits = null;
            if (currentByte == 0)
            { 
                // positive number
                resultDigits = positiveDecimalDigits; 
            } 
            else
            { 
                // negative number
                List negativeDecimalDigits = new List(TwoToThePowerOf(absoluteBitNumber));
                SubtractSecondDecimalFromFirst(negativeDecimalDigits, positiveDecimalDigits);
                resultDigits = negativeDecimalDigits; 
                result.Append('-');
            } 
            int d; 
            for (d = resultDigits.Count - 1; d >= 0; d--)
            { 
                if (resultDigits[d] != 0)
                    break;
            }
 
            if (d < 0 && asn1.Length > 0)
            { 
                // This is a special case where the result contains 0 
                result.Append(digitMap[0]);
            } 
            else
            {
                while (d >= 0)
                { 
                    result.Append(digitMap[resultDigits[d--]]);
                } 
            } 

            return result.ToString(); 
        }

        static byte[] TwoToThePowerOf(int n)
        { 
            lock (powersOfTwo)
            { 
                if (n >= powersOfTwo.Count) 
                {
                    for (int power = powersOfTwo.Count; power <= n; power++) 
                    {
                        List decimalDigits = new List(powersOfTwo[power - 1]);
                        byte carryover = 0;
                        for (int i = 0; i < decimalDigits.Count; i++) 
                        {
                            byte newValue = (byte)((decimalDigits[i] << 1) + carryover); 
                            decimalDigits[i] = (byte)(newValue % 10); 
                            carryover = (byte)(newValue / 10);
                        } 
                        if (carryover > 0)
                        {
                            decimalDigits.Add(carryover);
                            carryover = 0; 
                        }
                        powersOfTwo.Add(decimalDigits.ToArray()); 
                    } 
                }
                return powersOfTwo[n]; 
            }
        }

        static void AddSecondDecimalToFirst(List first, byte[] second) 
        {
            byte carryover = 0; 
            for (int i = 0; i < second.Length || i < first.Count; i++) 
            {
                if (i >= first.Count) 
                {
                    first.Add(0);
                }
                byte newValue; 
                if (i < second.Length)
                { 
                    newValue = (byte)(first[i] + second[i] + carryover); 
                }
                else 
                {
                    newValue = (byte)(first[i] + carryover);
                }
                first[i] = (byte)(newValue % 10); 
                carryover = (byte)(newValue / 10);
            } 
            if (carryover > 0) 
            {
                first.Add(carryover); 
            }
        }

        static void SubtractSecondDecimalFromFirst(List first, List second) 
        {
            byte borrow = 0; 
            for (int i = 0; i < second.Count; i++) 
            {
                int newValue = first[i] - second[i] - borrow; 
                if (newValue < 0)
                {
                    borrow = 1;
                    first[i] = (byte)(newValue + 10); 
                }
                else 
                { 
                    borrow = 0;
                    first[i] = (byte)newValue; 
                }
            }
            if (borrow > 0)
            { 
                for (int i = second.Count; i < first.Count; i++)
                { 
                    int newValue = first[i] - borrow; 
                    if (newValue < 0)
                    { 
                        borrow = 1;
                        first[i] = (byte)(newValue + 10);
                    }
                    else 
                    {
                        borrow = 0; 
                        first[i] = (byte)newValue; 
                        break;
                    } 
                }
            }
            DiagnosticUtility.DebugAssert(borrow == 0, "");
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK