Note: Using .Net 4.0
Consider the following piece of code.
String ad = "FE23658978541236";
String ad2 = "00FABE002563447E".ToLower();
try
{
PhysicalAddress.Parse(ad);
}
catch (Exception)
{
//We dont get here, all went well
}
try
{
PhysicalAddress.Parse(ad2);
}
catch (Exception)
{
//we arrive here for what reason?
}
try
{
//Ok, I do it myself then.
ulong dad2 = ulong.Parse(ad2, System.Globalization.NumberStyles.HexNumber);
byte[] bad2 = BitConverter.GetBytes(dad2);
if (BitConverter.IsLittleEndian)
{
bad2 = bad2.Reverse().ToArray<byte>();
}
PhysicalAddress pa = new PhysicalAddress(bad2);
}
catch (Exception ex)
{
//We don't get here as all went well
}
So an exception is thrown in PhysicalAddress.Parse method when trying to parse an address with lower case. When I look at the source code of .Net its totally clear to me why. Its because of the following piece of code.
if (value >= 0x30 && value <=0x39){
value -= 0x30;
}
else if (value >= 0x41 && value <= 0x46) {
value -= 0x37;
}
That is found within the Parse
method.
public static PhysicalAddress Parse(string address) {
int validCount = 0;
bool hasDashes = false;
byte[] buffer = null;
if(address == null)
{
return PhysicalAddress.None;
}
//has dashes?
if (address.IndexOf('-') >= 0 ){
hasDashes = true;
buffer = new byte[(address.Length+1)/3];
}
else{
if(address.Length % 2 > 0){ //should be even
throw new FormatException(SR.GetString(SR.net_bad_mac_address));
}
buffer = new byte[address.Length/2];
}
int j = 0;
for (int i = 0; i < address.Length; i++ ) {
int value = (int)address[i];
if (value >= 0x30 && value <=0x39){
value -= 0x30;
}
else if (value >= 0x41 && value <= 0x46) {
value -= 0x37;
}
else if (value == (int)'-'){
if (validCount == 2) {
validCount = 0;
continue;
}
else{
throw new FormatException(SR.GetString(SR.net_bad_mac_address));
}
}
else{
throw new FormatException(SR.GetString(SR.net_bad_mac_address));
}
//we had too many characters after the last dash
if(hasDashes && validCount >= 2){
throw new FormatException(SR.GetString(SR.net_bad_mac_address));
}
if (validCount%2 == 0) {
buffer[j] = (byte) (value << 4);
}
else{
buffer[j++] |= (byte) value;
}
validCount++;
}
//we too few characters after the last dash
if(validCount < 2){
throw new FormatException(SR.GetString(SR.net_bad_mac_address));
}
return new PhysicalAddress(buffer);
}
Can this be considered a bug? Or is it so very wrong to use a lower cased hex values in a string? Or is there some convention I am unaware of. Personally, I consider this programmer unfriendly.
From MSDN:
The address parameter must contain a string that can only consist of numbers and upper-case letters as hexadecimal digits. Some examples of string formats that are acceptable are as follows .... Note that an address that contains f0-e1-d2-c3-b4-a5 will fail to parse and throw an exception.
So you could simply do: PhysicalAddress.Parse(ad.ToUpper());