Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / mscorlib / system / security / util / hex.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*
7  * Hex.cs
8 // 
9 // <OWNER>Microsoft</OWNER>
10  *
11  * Operations to convert to and from Hex
12  *
13  */
14
15 namespace System.Security.Util
16 {
17     using System;
18     using System.Security;
19     using System.Diagnostics.Contracts;
20     internal static class Hex
21     {
22         // converts number to hex digit. Does not do any range checks.
23         static char HexDigit(int num) {
24             return (char)((num < 10) ? (num + '0') : (num + ('A' - 10)));
25         }
26         
27         public  static String EncodeHexString(byte[] sArray) 
28         {
29             String result = null;
30     
31             if(sArray != null) {
32                 char[] hexOrder = new char[sArray.Length * 2];
33             
34                 int digit;
35                 for(int i = 0, j = 0; i < sArray.Length; i++) {
36                     digit = (int)((sArray[i] & 0xf0) >> 4);
37                     hexOrder[j++] = HexDigit(digit);
38                     digit = (int)(sArray[i] & 0x0f);
39                     hexOrder[j++] = HexDigit(digit);
40                 }
41                 result = new String(hexOrder);
42             }
43             return result;
44         }
45
46         internal static string EncodeHexStringFromInt(byte[] sArray) {
47             String result = null;
48             if(sArray != null) {
49                 char[] hexOrder = new char[sArray.Length * 2];
50             
51                 int i = sArray.Length;
52                 int digit, j=0;
53                 while (i-- > 0) {
54                     digit = (sArray[i] & 0xf0) >> 4;
55                     hexOrder[j++] = HexDigit(digit);
56                     digit = sArray[i] & 0x0f;
57                     hexOrder[j++] = HexDigit(digit);
58                 }
59                 result = new String(hexOrder);
60             }
61             return result;
62         }
63         
64         public static int ConvertHexDigit(Char val)
65         {
66             if (val <= '9' && val >= '0')
67                 return (val - '0');
68             else if (val >= 'a' && val <= 'f')
69                 return ((val - 'a') + 10);
70             else if (val >= 'A' && val <= 'F')
71                 return ((val - 'A') + 10);
72             else
73                 throw new ArgumentException( Environment.GetResourceString( "ArgumentOutOfRange_Index" ) );  
74         }
75
76         
77         public static byte[] DecodeHexString(String hexString)
78         {
79             if (hexString == null)
80                 throw new ArgumentNullException( "hexString" );
81             Contract.EndContractBlock();
82                     
83             bool spaceSkippingMode = false;    
84                     
85             int i = 0;
86             int length = hexString.Length;
87             
88             if ((length >= 2) &&
89                 (hexString[0] == '0') &&
90                 ( (hexString[1] == 'x') ||  (hexString[1] == 'X') ))
91             {
92                 length = hexString.Length - 2;
93                 i = 2;
94             }
95             
96             // Hex strings must always have 2N or (3N - 1) entries.
97             
98             if (length % 2 != 0 && length % 3 != 2)
99             {
100                 throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidHexFormat" ) );
101             }                
102                 
103             byte[] sArray;
104                 
105             if (length >=3 && hexString[i + 2] == ' ')
106             {
107                 spaceSkippingMode = true;
108                     
109                 // Each hex digit will take three spaces, except the first (hence the plus 1).
110                 sArray = new byte[length / 3 + 1];
111             }
112             else
113             {
114                 // Each hex digit will take two spaces
115                 sArray = new byte[length / 2];
116             }
117                 
118             int digit;
119             int rawdigit;
120             for (int j = 0; i < hexString.Length; i += 2, j++) {
121                 rawdigit = ConvertHexDigit(hexString[i]);
122                 digit = ConvertHexDigit(hexString[i+1]);
123                 sArray[j] = (byte) (digit | (rawdigit << 4));
124                 if (spaceSkippingMode)
125                     i++;
126             }
127             return(sArray);    
128         }
129     }
130 }