C#中的哈希函数在本地主机开发服务器上返回的值与在生产服务器上返回的值不同
我有一个aspx应用程序,我在其中创建一个散列,将其发送到银行,以便进行货币交易。我遇到了一个非常奇怪的问题:当我在visual studio 2010的开发服务器中本地运行应用程序时,哈希值得到了正确的计算,但是在生产服务器中发布的应用程序中,哈希值不再得到正确的计算,它不会抛出任何错误,但是生成的哈希值不正确(说它不正确并不意味着它不是散列,但它不是预期的散列) 返回哈希的函数如下所示:C#中的哈希函数在本地主机开发服务器上返回的值与在生产服务器上返回的值不同,c#,asp.net,hash,sha1,C#,Asp.net,Hash,Sha1,我有一个aspx应用程序,我在其中创建一个散列,将其发送到银行,以便进行货币交易。我遇到了一个非常奇怪的问题:当我在visual studio 2010的开发服务器中本地运行应用程序时,哈希值得到了正确的计算,但是在生产服务器中发布的应用程序中,哈希值不再得到正确的计算,它不会抛出任何错误,但是生成的哈希值不正确(说它不正确并不意味着它不是散列,但它不是预期的散列) 返回哈希的函数如下所示: string codificar = afiliacion.ToString().Trim() +
string codificar = afiliacion.ToString().Trim() +
tienda.ToString().Trim() +
terminal.Trim() +
total_orden.ToString().Trim() +
moneda.ToString().Trim() +
numOrd.ToString().Trim();
SHA1 cod = new SHA1Managed();
UTF8Encoding codificado = new UTF8Encoding();
byte[] stream = codificado.GetBytes(codificar);
StringBuilder sb = new StringBuilder();
var hash = cod.ComputeHash(stream);
foreach (var b in hash)
{
sb.Append(b.ToString("X2"));
}
foreach (var laorden in categoriaBuscados)
{
TNumsOrdenAFoliosMovimiento registro = new TNumsOrdenAFoliosMovimiento();
registro.numOrden = laorden.NumOrden;
registro.Digest = sb.ToString().ToLower();
try
{
modelo.TNumsOrdenAFoliosMovimiento.AddObject(registro);
modelo.SaveChanges();
}
catch (Exception el)
{
Response.Write(el.Message);
}
<script type="text/javascript">
window.onload = function () {
var referencia = document.getElementById("referencia");
console.log(referencia.value);
referencia.value = getBytes(utf8_encode(referencia.value));
}
function getBytes(str) {
var bytes = [];
var charCode;
for (var i = 0; i < str.length; ++i) {
charCode = str.charCodeAt(i);
bytes.push((charCode & 0xFF00) >> 8);
bytes.push(charCode & 0xFF);
}
return bytes;
}
function utf8_encode(argString) {
if (argString === null || typeof argString === 'undefined') {
return '';
}
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
var utftext = '',
start, end, stringl = 0;
start = end = 0;
stringl = string.length;
for (var n = 0; n < stringl; n++) {
var c1 = string.charCodeAt(n);
var enc = null;
if (c1 < 128) {
end++;
} else if (c1 > 127 && c1 < 2048) {
enc = String.fromCharCode(
(c1 >> 6) | 192, (c1 & 63) | 128
);
} else if ((c1 & 0xF800) != 0xD800) {
enc = String.fromCharCode(
(c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
);
} else { // surrogate pairs
if ((c1 & 0xFC00) != 0xD800) {
throw new RangeError('Unmatched trail surrogate at ' + n);
}
var c2 = string.charCodeAt(++n);
if ((c2 & 0xFC00) != 0xDC00) {
throw new RangeError('Unmatched lead surrogate at ' + (n - 1));
}
c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
enc = String.fromCharCode(
(c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
);
}
if (enc !== null) {
if (end > start) {
utftext += string.slice(start, end);
}
utftext += enc;
start = end = n + 1;
}
}
if (end > start) {
utftext += string.slice(start, stringl);
}
return utftext;
}
</script>
任何建议都是非常受欢迎的,因为我不知道为什么会发生这种情况。我的意思是,从理论上讲,同一代码在本地版本和发布版本之间的工作方式不同是不可能的,不是吗?因为字符串不向用户显示,只用于生成哈希,所以更新
ToString
调用s到ToString(CultureInfo.InvariantCulture)
——这将确保在本地和生产服务器上使用相同的规则进行字符串化
string codificar = afiliacion.ToString(CultureInfo.InvariantCulture).Trim() +
tienda.ToString(CultureInfo.InvariantCulture).Trim() +
terminal.Trim() +
total_orden.ToString(CultureInfo.InvariantCulture).Trim() +
moneda.ToString(CultureInfo.InvariantCulture).Trim() +
numOrd.ToString(CultureInfo.InvariantCulture).Trim();
由于字符串不显示给用户,并且仅用于生成哈希,请更新对
ToString(CultureInfo.InvariantCulture)
的ToString调用,以确保在本地和生产服务器上使用相同的规则对字符串进行字符串化
string codificar = afiliacion.ToString(CultureInfo.InvariantCulture).Trim() +
tienda.ToString(CultureInfo.InvariantCulture).Trim() +
terminal.Trim() +
total_orden.ToString(CultureInfo.InvariantCulture).Trim() +
moneda.ToString(CultureInfo.InvariantCulture).Trim() +
numOrd.ToString(CultureInfo.InvariantCulture).Trim();
问题似乎出在生产服务器中的dll mscorlib上,它的版本与我在开发中使用的版本不同。因此,最终我想出了另一个解决方案,而不是使用UTF8Encoding类从字符串中获取字节,我使用javascript构建了字节,然后将它们传递给后面的代码。现在两个散列相等,不再有错误。谢谢大家的评论。我仍然不知道如何结束这里的问题
我用于构建字节数组的javascript代码如下所示:
string codificar = afiliacion.ToString().Trim() +
tienda.ToString().Trim() +
terminal.Trim() +
total_orden.ToString().Trim() +
moneda.ToString().Trim() +
numOrd.ToString().Trim();
SHA1 cod = new SHA1Managed();
UTF8Encoding codificado = new UTF8Encoding();
byte[] stream = codificado.GetBytes(codificar);
StringBuilder sb = new StringBuilder();
var hash = cod.ComputeHash(stream);
foreach (var b in hash)
{
sb.Append(b.ToString("X2"));
}
foreach (var laorden in categoriaBuscados)
{
TNumsOrdenAFoliosMovimiento registro = new TNumsOrdenAFoliosMovimiento();
registro.numOrden = laorden.NumOrden;
registro.Digest = sb.ToString().ToLower();
try
{
modelo.TNumsOrdenAFoliosMovimiento.AddObject(registro);
modelo.SaveChanges();
}
catch (Exception el)
{
Response.Write(el.Message);
}
<script type="text/javascript">
window.onload = function () {
var referencia = document.getElementById("referencia");
console.log(referencia.value);
referencia.value = getBytes(utf8_encode(referencia.value));
}
function getBytes(str) {
var bytes = [];
var charCode;
for (var i = 0; i < str.length; ++i) {
charCode = str.charCodeAt(i);
bytes.push((charCode & 0xFF00) >> 8);
bytes.push(charCode & 0xFF);
}
return bytes;
}
function utf8_encode(argString) {
if (argString === null || typeof argString === 'undefined') {
return '';
}
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
var utftext = '',
start, end, stringl = 0;
start = end = 0;
stringl = string.length;
for (var n = 0; n < stringl; n++) {
var c1 = string.charCodeAt(n);
var enc = null;
if (c1 < 128) {
end++;
} else if (c1 > 127 && c1 < 2048) {
enc = String.fromCharCode(
(c1 >> 6) | 192, (c1 & 63) | 128
);
} else if ((c1 & 0xF800) != 0xD800) {
enc = String.fromCharCode(
(c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
);
} else { // surrogate pairs
if ((c1 & 0xFC00) != 0xD800) {
throw new RangeError('Unmatched trail surrogate at ' + n);
}
var c2 = string.charCodeAt(++n);
if ((c2 & 0xFC00) != 0xDC00) {
throw new RangeError('Unmatched lead surrogate at ' + (n - 1));
}
c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
enc = String.fromCharCode(
(c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
);
}
if (enc !== null) {
if (end > start) {
utftext += string.slice(start, end);
}
utftext += enc;
start = end = n + 1;
}
}
if (end > start) {
utftext += string.slice(start, stringl);
}
return utftext;
}
</script>
window.onload=函数(){
var referencea=document.getElementById(“referencea”);
console.log(referecia.value);
referencea.value=getBytes(utf8_编码(referencea.value));
}
函数getBytes(str){
var字节=[];
var字符码;
对于(变量i=0;i>8);
字节推送(charCode&0xFF);
}
返回字节;
}
函数utf8_编码(argString){
如果(argString===null | | argString的类型==='undefined'){
返回“”;
}
变量字符串=(argString+“”);//.replace(/\r\n/g,“\n”)。replace(/\r/g,“\n”);
var utftext=“”,
开始,结束,stringl=0;
开始=结束=0;
stringl=string.length;
对于(var n=0;n127&&c1<2048){
enc=String.fromCharCode(
(c1>>6)| 192,(c1和63)| 128
);
}否则如果((c1和0xF800)!=0xD800){
enc=String.fromCharCode(
(c1>>12)224,((c1>>6)和63)128,(c1和63)128
);
}else{//代理项对
如果((c1&0xFC00)!=0xD800){
抛出新的RangeError(“+n”处的不匹配跟踪代理项);
}
var c2=字符串.charCodeAt(++n);
如果((c2&0xFC00)!=0xDC00){
抛出新的RangeError(“+(n-1)”处不匹配的lead代理项);
}
c1=((c1&0x3FF)>18)| 240、((c1>>12)&63)| 128、((c1>>6)&63)| 128、(c1&63)| 128
);
}
如果(enc!==null){
如果(结束>开始){
utftext+=string.slice(开始、结束);
}
utftext+=enc;
开始=结束=n+1;
}
}
如果(结束>开始){
utftext+=string.slice(开始,stringl);
}
返回utftext;
}
问题似乎出在生产服务器中的dll mscorlib上,该版本与我在开发中使用的版本不同。因此,最终我提出了另一个解决方案,并没有使用UTF8Encoding类从字符串中获取字节,而是使用javascript构建了字节,然后将它们传递给后面的代码。现在两个散列相等,不再有错误。谢谢大家的评论。我仍然不知道如何结束这里的一个问题
我用于构建字节数组的javascript代码如下所示:
string codificar = afiliacion.ToString().Trim() +
tienda.ToString().Trim() +
terminal.Trim() +
total_orden.ToString().Trim() +
moneda.ToString().Trim() +
numOrd.ToString().Trim();
SHA1 cod = new SHA1Managed();
UTF8Encoding codificado = new UTF8Encoding();
byte[] stream = codificado.GetBytes(codificar);
StringBuilder sb = new StringBuilder();
var hash = cod.ComputeHash(stream);
foreach (var b in hash)
{
sb.Append(b.ToString("X2"));
}
foreach (var laorden in categoriaBuscados)
{
TNumsOrdenAFoliosMovimiento registro = new TNumsOrdenAFoliosMovimiento();
registro.numOrden = laorden.NumOrden;
registro.Digest = sb.ToString().ToLower();
try
{
modelo.TNumsOrdenAFoliosMovimiento.AddObject(registro);
modelo.SaveChanges();
}
catch (Exception el)
{
Response.Write(el.Message);
}
<script type="text/javascript">
window.onload = function () {
var referencia = document.getElementById("referencia");
console.log(referencia.value);
referencia.value = getBytes(utf8_encode(referencia.value));
}
function getBytes(str) {
var bytes = [];
var charCode;
for (var i = 0; i < str.length; ++i) {
charCode = str.charCodeAt(i);
bytes.push((charCode & 0xFF00) >> 8);
bytes.push(charCode & 0xFF);
}
return bytes;
}
function utf8_encode(argString) {
if (argString === null || typeof argString === 'undefined') {
return '';
}
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
var utftext = '',
start, end, stringl = 0;
start = end = 0;
stringl = string.length;
for (var n = 0; n < stringl; n++) {
var c1 = string.charCodeAt(n);
var enc = null;
if (c1 < 128) {
end++;
} else if (c1 > 127 && c1 < 2048) {
enc = String.fromCharCode(
(c1 >> 6) | 192, (c1 & 63) | 128
);
} else if ((c1 & 0xF800) != 0xD800) {
enc = String.fromCharCode(
(c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
);
} else { // surrogate pairs
if ((c1 & 0xFC00) != 0xD800) {
throw new RangeError('Unmatched trail surrogate at ' + n);
}
var c2 = string.charCodeAt(++n);
if ((c2 & 0xFC00) != 0xDC00) {
throw new RangeError('Unmatched lead surrogate at ' + (n - 1));
}
c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
enc = String.fromCharCode(
(c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128
);
}
if (enc !== null) {
if (end > start) {
utftext += string.slice(start, end);
}
utftext += enc;
start = end = n + 1;
}
}
if (end > start) {
utftext += string.slice(start, stringl);
}
return utftext;
}
</script>
window.onload=函数(){
var referencea=document.getElementById(“referencea”);
console.log(referecia.value);
referencea.value=getBytes(utf8_编码(referencea.value));
}
函数getBytes(str){
var字节=[];
var字符码;
对于(变量i=0;i>8);
字节推送(charCode&0xFF);
}
返回字节;
}
函数utf8_编码(argString){
如果(argString===null | | argString的类型==='undefined'){
返回“”;
}
变量字符串=(argString+“”);//.replace(/\r\n/g,“\n”)。replace(/\r/g,“\n”);
var utftext=“”,
开始,结束,stringl=0;
开始=结束=0;
斯特林