2

I've almost finished converting a PHP script to a C# one to use in ASP.net.

I've already converted this to match the the correct result so far:-

function sign_url($url, $key, $secret)
{
    if (strpos($url,'?') !== false)
    {
        $url .= "&";
    }
    else
    {
        $url .= "?";
    }
    $url .= "ApplicationKey=" . $key;

    $signature = hash_hmac("sha1", urldecode($url), $secret);
    $url .= "&Signature=" . hex_to_base64($signature);

    return $url;
}

Here is the part i'm struggling with:-

function hex_to_base64($hex){
  $return = '';
  foreach(str_split($hex, 2) as $pair){
    $return .= chr(hexdec($pair));
  }
  return base64_encode($return);
}

From what i can gather it splits the input string ($hex) into sets of 2 characters.
It then converts these hexadecimal strings to decimal numbers before getting the chr() value of this number.
Storing all these conversions in a $return string.
Finally it does the base 64 conversion.

I'm struggling to find the best way to do this in C#, particularly the splitting into 2 characters while doing the other conversions.

TarasB
  • 2,407
  • 1
  • 24
  • 32
Porkster
  • 85
  • 1
  • 7
  • `before getting the chr()` what exactly is that supposed to do? As I understand it you need to parse the two character string as a hex number and then get the equivalent `char`. Is that correct? – Matt Burland Nov 19 '14 at 15:11
  • I've now added the first part of the code for clarity. From what I can gather you are correct. It passes in a string such as 'B709E79EA2769A409FF87FE87AC1F6799EE0917E' – Porkster Nov 19 '14 at 15:21
  • You might want to take a look at: http://csharpfunctions.blogspot.co.uk/2010/03/convert-hex-formatted-string-to-base64.html and/or http://stackoverflow.com/questions/7784345/conversion-between-base64string-and-hexadecimal – Jamiec Nov 19 '14 at 15:23

4 Answers4

2

Old, good, C-style code that do not use LINQ and megabytes of other libraries:

static string HexToBase64(string hex)
{
    byte[] buf = new byte[hex.Length / 2];
    for (int i = 0; i < hex.Length / 2; i++)
    {
        buf[i] = Convert.ToByte(hex.Substring(i*2,2), 16);
    }
    return Convert.ToBase64String(buf);
}
Konrad Kokosa
  • 16,563
  • 2
  • 36
  • 58
0

Try these:

str_split = String.Split() (http://msdn.microsoft.com/en-us/library/system.string.split(v=vs.110).aspx)

base64_encode = Convert.ToBase64String() (http://msdn.microsoft.com/en-us/library/system.convert.tobase64string(v=vs.110).aspx)

chr = Convert.ToChar() (http://msdn.microsoft.com/en-us/library/system.convert.tochar(v=vs.110).aspx)

hexdec = .ToString("X") (http://msdn.microsoft.com/en-us/library/8wch342y(v=vs.110).aspx)

hash_hmac = SHA1.ComputeHash() (http://msdn.microsoft.com/en-us/library/s02tk69a(v=vs.110).aspx)
John
  • 6,503
  • 3
  • 37
  • 58
Ricardo Peres
  • 13,724
  • 5
  • 57
  • 74
0

You can do it using two amazing .Net technologies - LINQ and Rx:

private static string HexStringToBase64String(string hexString)
{
    var byteArray = hexString
        .ToObservable()
        .Buffer(2)
        .Select(pair => new string(pair.ToArray()))
        .Select(numberString => Byte.Parse(numberString, NumberStyles.HexNumber))
        .ToEnumerable()
        .ToArray();

    return Convert.ToBase64String(byteArray);
}
galenus
  • 2,087
  • 16
  • 24
0

There's no need to split each hex byte into two characters, or loop through each character pair for that matter.

Take a look at the following questions:

How to convert numbers between hexadecimal and decimal in C#?

How can I convert a hex string to a byte array?

I would do something like this

public static string HexToBase64String(string hex)
{
    if (string.IsNullOrEmpty(hex) || hex.Length % 2 == 1)
        throw new ArgumentException("Invalid hex value", "hex");

    var bytes = Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
    return System.Convert.ToBase64String(bytes);
}
Community
  • 1
  • 1
Lee Greco
  • 743
  • 2
  • 11
  • 23