微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Object Nested Uint8Array(32) to String to btoa to localStorage to atob to Uint8Array(32)

如何解决Object Nested Uint8Array(32) to String to btoa to localStorage to atob to Uint8Array(32)

我在 javascript 方面的技能很少,我不确定如何在将原始 Uint8Array(32) 发送到 localStorage、解码并转换回 Uint8Array(32) 后获取它。下面您将看到我尝试将私钥字符串化,然后对其进行 base64 编码,以便将其发送到 localStorage 以供以后使用:

window.base642Array = function(base64) {
    var binStr = window.atob(base64);
    console.log("binStr"+ binStr);
    var l = binStr.length;
    var bytes = new Uint8Array(l);
    for (var i = 0; i < l; i++) {
        bytes[i] = binStr.charCodeAt(i);
    }
    return bytes.buffer;
}

在这里你会注意到我正在尝试获取私钥,以便我可以通过从 localStorage 中获取 base64 编码的字符串并从中创建一个新的 Uint8Array 来生成相应的公钥:

window.genPKey = function()
{
    console.log("getSKey flag: 0");

    var SKey = getSKey();

    console.log("getSKey flag: 1");

    var publicKey;
    if(SKey != null || undefined)
    {
        console.log(SKey);

        console.log("getSKey flag: 2");

        publicKey = eccrypto.getPublic(SKey);

        console.log("getSKey flag: 3");

        localStorage.setItem("pkey",window.btoa(JSON.stringify(publicKey)));

        return;

    }

    console.log("getSKey flag: alt");

    genSKey();
    genPKey();

    return;
window.getSKey = function()
{
    console.log("getSKey flag: 0");

    var SKey = localStorage.getItem("skey");

    var skey = base642Array(SKey);

    console.log("getSKey flag: 1");

    console.log("getSKey flag: 2");

    console.log(skey);

    return skey;
}
Uint8Array(32) [247,145,236,54,52,10,202,187,35,79,42,141,230,76,228,2,109,72,92,221,139,235,147,244,149,220,196,175,11,128]
0: 247
1: 145
2: 236
3: 54
4: 52
5: 10
6: 202
7: 187
8: 35
9: 79
10: 42
11: 141
12: 230
13: 76
14: 228
15: 2
16: 109
17: 228
18: 72
19: 92
20: 221
21: 139
22: 235
23: 147
24: 244
25: 10
26: 149
27: 220
28: 196
29: 175
30: 11
31: 128
offset: (...)
parent: (...)
buffer: (...)
byteLength: (...)
byteOffset: (...)
length: (...)
Symbol(Symbol.toStringTag): (...)
__proto__: Uint8Array

在这里您会看到输入的结果与输出的结果不同:

ArrayBuffer(141) {}
[[Int8Array]]: Int8Array(141)
[0 … 99]
[100 … 140]
__proto__: TypedArray
[[Uint8Array]]: Uint8Array(141)
[0 … 99]
[100 … 140]
__proto__: TypedArray
byteLength: (...)
__proto__: ArrayBuffer
byteLength: (...)
constructor: ƒ ArrayBuffer()
slice: ƒ slice()
Symbol(Symbol.toStringTag): "ArrayBuffer"
get byteLength: ƒ byteLength()
__proto__: Object
[[IsDetached]]: false

{{1}}

我认为问题可能在于使用 JSON.stringify 将嵌套的 Uint8Array 转换为字符串,但我不确定其他方法可以使此功能正常运行。

为什么对象输入和对象输出不一样?我想学习如何做到这一点,帮助对我来说意味着整个世界。

解决方法

一些问题:

  • 尽管您使用了 JSON.stringify,但您从未使用过相反的操作,即 JSON.parse

  • 您使用了 charCodeAt,但您从未使用过相反的操作,即 String.fromCharCodecharCodeAt 与您制作字符串的操作无关,因此应该删除它。

  • 在调试此类问题时,您应该消除步骤。例如,您会发现以下步骤与您的问题无关:

    • 从本地存储中存储和检索;
    • 与base64编码相互转换;
    • 使用加密库

    问题在于将类型化数组转换为字符串并返回。

转换为字符串和转换回类型数组根本不是彼此的颠倒。

要解决此问题,我建议将您必须调用的调用更改为 JSON.stringify,以便将字符串化为数组表示法(以 [ 开头)而不是普通对象表示法(以{)。所以改变:

JSON.stringify(secretKey);

到:

JSON.stringify(Array.from(secretKey));

然后将该字符串转回类型化数组,使用 JSON.parse:

new Uint8Array(JSON.parse(str))

这是一个没有不相关步骤的小演示:

function fromTypedArrayToString(arr) {
    return JSON.stringify([...arr]);
}

function fromStringToTypedArray(str) {
    return new Uint8Array(JSON.parse(str));
}

function compareTypedArrays(arr1,arr2) {
    if (arr1.length !== arr2.length) return false;
    for (let i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i]) return false;
    }
    return true;
}  

// Demo: make a typed array with all possible values
let arr = new Uint8Array([...Array(256).keys()]);
let str = fromTypedArrayToString(arr);
let arr2 = fromStringToTypedArray(str);
let consistent = compareTypedArrays(arr,arr2);
console.log("Is the result consistent:",consistent);

您应该能够将其应用到您的代码中,并逐步添加:

  • base64 编码,虽然我看不到它的好处:字符串的大小会增长 30%。你可以没有这个。
  • 本地存储
  • 加密模块

在继续下一步之前,请继续检查操作是否可以反转,返回类型化数组的原始值,就像我在上面的代码片段中所做的那样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?