Skip to content

Instantly share code, notes, and snippets.

@kensykora
Created May 12, 2015 13:51
Show Gist options
  • Save kensykora/eb3f74be5ed4a278b46c to your computer and use it in GitHub Desktop.
Save kensykora/eb3f74be5ed4a278b46c to your computer and use it in GitHub Desktop.
Code Challenge for Nerdery .Net Newsletter #2
using System;
using Newtonsoft.Json;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Cryptography;
public class Program
{
static string INPUT = @"{
""author_name"": ""Robert Jordan"",
""book_title"": ""Knife of Dreams"",
""series"": ""The Wheel of Time, Book 11"",
""publisher"": ""Tor Fantasy"",
""published_date"": ""November 28, 2006""
}";
public static void Main()
{
Console.Out.WriteLine(GenerateQuerystring(INPUT));
}
public static string GenerateQuerystring(string input)
{
var book = JsonConvert.DeserializeObject<Book>(input);
var result = new StringBuilder();
foreach (var property in typeof (Book).GetProperties().OrderBy(x => x.Name))
{
result.Append(property.Name);
result.Append("=");
result.Append(HttpUtility.UrlEncode(property.GetValue(book).ToString()));
result.Append("&");
}
result.Append("timestamp=");
result.Append(GetUnixTimestamp());
result.Append("&signature=");
result.Append(HttpUtility.UrlEncode(Hash(result.ToString() + "1234MySuperSecretKey4321")));
return result.ToString();
}
public static string Hash(string input)
{
var temp = Encoding.UTF8.GetBytes(input);
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(temp);
return Convert.ToBase64String(hash);
}
}
public static long GetUnixTimestamp()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1));
return (long)timeSpan.TotalSeconds;
}
public class Book
{
public string author_name { get; set; }
public string book_title { get; set; }
public string series { get; set; }
public string publisher { get; set; }
//This should be a DateTime (but and we're not doing any Date maths)
//but would require adding a ton of complexity to the reflection logic above.
public string published_date { get; set; }
}
}
Copy link

ghost commented May 12, 2015

Just a thought, but wouldn't you want to create the signature hash before appending the '&signature=' param, to not include the param in the hash too?

...
    result.Append("timestamp=");
    result.Append(GetUnixTimestamp());
    var signature = HttpUtility.UrlEncode(Hash(result.ToString() + "1234MySuperSecretKey4321"));
    result.Append("&signature=");
    result.Append(signature);
    return result.ToString(); // generates: CX5NjWdEJI7oF%2bkj8xBNCfkgs%2b0%3d

Instead of

...
    result.Append("timestamp=");
    result.Append(GetUnixTimestamp());
    result.Append("&signature=");
    result.Append(HttpUtility.UrlEncode(Hash(result.ToString() + "1234MySuperSecretKey4321")));
    return result.ToString(); //generates: RiDSg2bTWGUi4WISKjDUAo2mK7Q%3d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment