【问题标题】:Hash function in C# returns different value on localhost developing server than in production serverC# 中的哈希函数在 localhost 开发服务器上返回的值与在生产服务器上不同
【发布时间】:2014-10-07 01:30:38
【问题描述】:

我有一个 aspx 应用程序,我在其中生成一个散列以将其发送到银行,以便进行货币交易。我遇到了一个非常奇怪的问题:当我在 Visual Studio 2010 的开发服务器中本地运行应用程序时,哈希计算正确,但在生产服务器中已发布的应用程序中,哈希不再正确计算,它没有'不抛出任何错误,但生成的散列不正确(说不正确并不意味着它不是散列,而是不是预期的散列)

返回哈希的函数如下:

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);
    }

非常欢迎任何建议,因为我不知道为什么会发生这种情况。我的意思是,相同的代码在本地版本和发布版本之间的工作方式不同,理论上是不可能的,不是吗?

【问题讨论】:

  • 您能否详细说明您确定它不是正确哈希的方式?
  • 举一个字符串codificar的例子和你期望得到的哈希值。
  • 32 位 vs 64 位是这里最可能的原因之一。
  • @MarkNash 这不一样。 GetHashCode() 此处未使用。
  • ToString 可以根据机器的语言环境产生不同的表示。它们在本地机器和生产机器上是否相同?

标签: c# asp.net hash sha1


【解决方案1】:

由于字符串不向用户显示并且仅用于生成哈希,请将 ToString 调用更新为 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();

【讨论】:

  • 我尝试使用像 registro.Digest = sb.ToString(CultureInfo.InvariantCulture).ToLower(); 这样的调用,但它显示错误“没有重载方法 ToString() 需要一个参数”。我尝试先定义cultureinfo CultureInfo Inv = new CultureInfo(""); 然后ToString(Inv) 但我仍然得到那个错误。有什么办法呢?
  • @gerardoflores 我指的是 ToStrings,当你正在构建 codificar 时。
  • 我相信与 StringBuilder 一起使用的 ToString() 方法不包括只有一个参数的重载,只有 ToString(int startindex, int length)。所以我无法更新转换(最初) StringBuilder 的 ToString 方法
  • @gerardoflores 更新了我的答案,以便更清楚地说明应该在哪里使用 InvariantCulture。 afiliaciontienda 等等,StringBuilders 也一样吗?
  • 谢谢,这似乎是个好主意,但不幸的是它不起作用,它仍然只在本地运行时返回正确的哈希(叹气)
【解决方案2】:

问题似乎出在生产服务器中的 dll mscorlib 上,该版本与我在开发中使用的版本不同。所以最终我想出了另一个解决方案,而不是使用 UTF8Encoding 类并从字符串中获取字节,而是使用 javascript 构建字节,然后将它们传递给后面的代码。现在两个哈希值相等,不再有错误。谢谢大家的cmets。我仍然不知道如何在这里结束一个问题。

我用来构建字节数组的javascript代码如下:

<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>

【讨论】:

    猜你喜欢
    • 2015-10-06
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2016-01-28
    • 2012-06-28
    • 1970-01-01
    相关资源
    最近更新 更多