在 JavaScript 中将非纯函数转换为纯函数的策略

What strategy to turn non-pure functions into a pure functions in JavaScript

我在 javascript 开始学习函数式编程。这可能是一个愚蠢的问题,但我正在尝试解决以函数式方式编写的非纯函数。

我的问题是在函数式编程范例中应该使用什么策略来实现这一点。

const crypto = require('crypto');

const encrypt = (data, publicKey) => {
    if (publicKey === undefined ) throw 'Missing public key.';

    const bufferToEncrypt = Buffer.from(data);
    const encrypted = crypto.publicEncrypt({
        key: publicKey
    }, bufferToEncrypt);

    return encrypted;

};

纯函数有两个标准。

纯函数准则 1:调用具有相同值的函数必须始终产生相同的 return 值

在进行非对称加密时这是不可能的,因为每次操作都会生成一个随机会话密钥。会话密钥使用 public 密钥加密,然后会话密钥用于加密负载。 returned 值通常只是两个值的编码版本:(1) 公钥加密的会话密钥,以及 (2) 会话密钥加密的负载。

每次调用该函数时,这两个值都会不同,因为会话密钥每次都会不同。

然而,尽管 return 值不相等,但我认为它们 语义相等 —— 也就是说,如果你用匹配私钥,解密后的值将比较相等。

加密有效地混淆了值是否相等,对于加密来说这是一件好事我们不希望比较在不同时间生成的两条加密消息没有有解密密钥。那将是一个安全风险。

因此,我认为此函数在语义上符合此标准,但 如果没有 public 键,我们无法判断。

纯函数准则 2:函数没有可观察到的副作用

这一点应该很明显:写入磁盘是一种副作用,写入全局变量是一种副作用,等等。我们应该无法区分调用前后的状态差异函数。

从技术上讲,会话密钥的生成将需要使用系统的安全随机数生成器。这将消耗一些熵。 运行函数后,熵变少,可以测量

但是,我认为可以忽略这种副作用,因为 任何需要安全随机数的东西 都会有同样的问题,而这更像是 安全随机数生成器的实现细节

这就像声称需要大量 CPU 时间的函数有副作用,因为 运行 它增加了进程的 CPU 时间计数器。是副作用吗?技术上……也许?但没有一个有理智的人会认为这是副作用。

结论

我会调用这个函数"semantically pure."如果你问我这是不是一个纯函数并且只接受了一个没有限定的yes/no答案,我会告诉你"yes."