Node.js拼接方式的变化?

3
我正在尝试调试另一位程序员留下来让我维护的代码。我刚刚尝试将node.js 5升级到node.js 8,并且我的某些请求的数据库查询返回“找不到键”的错误。我们使用couchbase作为数据库,我们的文档键是为了安全而“加密”的。因此,我们可能有一个以“User_myemail@gmail.com”开头的键,但是我们使用以下方法进行加密:
function _GetScrambledKey(dbKey)
{
    //select encryption key based on db key content
    var eKeyIndex = CalculateEncryptionKeyIndex(dbKey, eKeys.length);
    var sha = CalculateSHA512(dbKey + eKeyIndex);
    return sha;
}

function CalculateEncryptionKeyIndex(str, max)
{
    var hashBuf = CalculateSHA1(str);
    var count = 0;
    for (var i = 0; i < hashBuf.length; i++)
    {
        count += hashBuf[i];
        count = count % max;
    }
    return count;
}

我们随后查询couchbase,获取该文档的信息。
cb.get("ECB_"+encryptedKey, opts, callback);

在node5中,这个工作正常,但在node8中,我们有些文档返回正常,而另一些则返回缺失。我把"ECB_"+encryptedKey输出为int数组,结果却更加混淆了我。它们在node5和node8上是不同的,但只有一个字符在数组中间不同。
在两个版本上输出加密后的键值对应的int数组如下:
188, 106, 14, 227, 211, 70, 94, 97, 63, 130, 78, 246, 155, 65, 6, 148, 62, 215, 47, 230, 211, 109, 35, 99, 21, 60, 178, 74, 195, 13, 233, 253, 187, 142, 213, 213, 104, 58, 168, 60, 225, 148, 25, 101, 155, 91, 122, 77, 2, 99, 102, 235, 26, 71, 159, 99, 6, 47, 162, 152, 58, 181, 21, 175
然后以相同的方式输出连接后的字符串,结果略有不同:
这是node8的输出:Node8 key: 69,67,66,95,65533,106,14,65533,65533,70,94,97,63,65533,78,65533,65533,65,6,65533,62,65533,47,65533,65533,109,35,99,21,60,65533,74,65533,13,65533,65533,65533,65533,65533,65533,104,58,65533,60,65533,25,101,65533,91,122,77,2,99,102,65533,26,71,65533,99,6,47,65533,65533,58,65533,21,65533 这是node5的输出:Node5 key: 69,67,66,95,65533,106,14,65533,65533,70,94,97,63,65533,78,65533,65533,65,6,65533,62,65533,47,65533,65533,109,35,99,21,60,65533,74,65533,13,65533,65533,65533,65533,65533,65533,104,58,65533,60,65533,65533,25,101,65533,91,122,77,2,99,102,65533,26,71,65533,99,6,47,65533,65533,58,65533,21,65533

我不得不通过差异工具来查看区别,enter image description here将其与原始的预附加数组进行比较,似乎在node8中只是删除了225。225是否重要?除非这是一个错误,否则我无法理解如何可能。有人有任何想法吗?


在那行代码之前,你尝试过使用 console.log(typeof encryptedKey) 吗?如果它是一个字符串,那么连接很简单。如果它是一个对象,那么就有可能会有变化。 - squgeim
我做了,是的。它是一个对象。我还运行了JSON.stringify和5和6中都是一样的 json: {"type":"Buffer","data":[26,66,54.....]} 如果连接已经改变,那么我需要找到一种方法来恢复原始功能。 - Real World
复合对象的 toString 在这里可能只会返回 [object Object]。在此之前,它绝对不起作用。你确定 encryptedKey 以前只是一个数组,但现在你已经做了一些更改,它变成了 {type:..., data:...} 吗?我敢打赌你以前有 ECB_26,66,54,但在这里进行了一些更改后出现了问题。 - Wiktor Zychla
1
从外观上看,encryptedKey 是一个 Node Buffer,它有一个 toString 方法,所以我不认为你会得到 [object Object]。他们给出的示例是它的 JSON 表示形式,而不是对象的实际结构。@RealWorld - 我建议检查 encryptedKey.toString() 在两个版本上是否返回相同的值。 - Joe Clay
另外,如果你看到那个老程序员,就扇他一巴掌,因为他依赖于 Node 默认字符串表示不会改变 :p - Joe Clay
显示剩余2条评论
2个回答

0

你正在面临的许多问题,包括字符串连接,可以使用ES6的新特性进行清理,这些特性在node 8中可用。

总的来说,应避免使用+运算符进行字符串连接,而应改用字符串字面值。在你的情况下,你应该将"ECB_"+encryptedKey替换为`ECB_${encryptedKey}`

此外,如果你想要输出这个连接字符串中整数值的内容,那么最好使用.join、扩展运算符(...)和Node的Buffer类,如下所示:

let encKey = `ECB_${encryptedKey}`;
let tmpBuff = Buffer.from(encKey);
let buffArrVals = [...tmpBuff];
console.log(buffArrVals.join(','));

此外,如果可以的话,您真的应该避免在函数块内使用像样本代码中存在的varvar执行一种称为变量提升的操作,并导致变量在声明它的范围之外变得可用,这很少是预期的。从Node 6+开始,建议使用letconst进行变量声明,以确保它们保持在声明它们的块的作用域内。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接