我有一种算法可以用来在调用更新操作时生成并返回一个checkSum。第二次更新需要发送给定的校验和,以证明对象完全相同。否则,将引发异常。
这是我用来管理校验和的课程:
public class TokenUpdate
{
internal readonly DateTime expireDateTime;
private static readonly Object locker = new Object();
internal readonly byte[] _dataTokenKey;
public TokenUpdate(object insuranceAgreement, DateTime newExpireDateTime)
{
expireDateTime = newExpireDateTime;
_dataTokenKey = GetSignedToken(insuranceAgreement);
}
public TokenUpdate(byte[] dataTokenKey, DateTime newExpireDateTime)
{
expireDateTime = newExpireDateTime;
_dataTokenKey = dataTokenKey;
}
public bool IsExpired
{
get
{
return !(expireDateTime > DateTime.Now);
}
}
public byte[] GetSignedToken(object insuranceAgreement)
{
byte[] tokenKey;
byte[] tokenData;
// serialize data in byte[]
using (var ms = new MemoryStream())
{
using (var writer = new BinaryWriter(ms))
{
writer.Write(ObjectToByteArray(insuranceAgreement));
tokenData = ms.ToArray();
}
}
using (var sha1 = new SHA256Managed())
{
tokenKey = sha1.ComputeHash(tokenData);
}
return tokenKey;
}
public string GetTokenString()
{
byte[] tokenData;
// serialize data in byte[]
using (var ms = new MemoryStream())
{
using (var writer = new BinaryWriter(ms))
{
writer.Write(expireDateTime.Ticks);
tokenData = ms.ToArray();
}
}
return Convert.ToBase64String(tokenData.Concat(_dataTokenKey).ToArray());
}
public static TokenUpdate BuildToken(object insuranceAgreement, DateTime expireDateTime)
{
if (insuranceAgreement == null)
{
return null;
}
return new TokenUpdate(insuranceAgreement, expireDateTime);
}
public static bool AreEqual(TokenUpdate token, object toCompare)
{
var compareToken = new TokenUpdate(toCompare, DateTime.Now);
return token._dataTokenKey.SequenceEqual(compareToken._dataTokenKey);
}
public static TokenUpdate GetTokenFromString(string tokenString)
{
TokenUpdate returnedToken = null;
byte[] buffer;
try
{
buffer = Convert.FromBase64String(tokenString);
}
catch (FormatException)
{
return null;
}
if (buffer.Length != 40)
{
return null;
}
var data = buffer.Take(buffer.Length - 32).ToArray();
var sig = buffer.Skip(data.Length).Take(32).ToArray();
using (var ms = new MemoryStream(data))
using (var reader = new BinaryReader(ms))
{
var ticks = reader.ReadInt64();
var expires = new DateTime(ticks);
returnedToken = new TokenUpdate(sig, expires);
}
return returnedToken;
}
internal static byte[] ObjectToByteArray(object objectToSerialize)
{
if (objectToSerialize == null)
{
return null;
}
MemoryStream fs = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
try
{
//Here's the core functionality! One Line!
//To be thread-safe we lock the object
lock (locker)
{
formatter.Serialize(fs, objectToSerialize);
}
return fs.ToArray();
}
catch (SerializationException se)
{
throw;
}
finally
{
fs.Close();
}
}
}
通过一些单元测试,一切都很好,但是运行一些压力测试表明,在30%的情况下,第二次更新被拒绝,因为将校验和与从数据库中数据生成的校验和进行比较的比较失败
我检查了一下,几乎可以确定其他两个之间没有内部更新。
我想知道,与SHA256Managed
类相关的哈希算法是否与系统datetime的mac地址相关?
因为我们负载均衡,所以可能会导致问题。