PHP函数date("c")、hash_hmac('sha512', "str1", "str2")及pack("H*", $secretkey)的Elixir等价实现及代码转换咨询
没问题!我来帮你把这段PHP代码转换成等价的Elixir实现,先逐个拆解每个PHP函数对应的Elixir写法,再给出完整代码:
1. pack("H*", $secretkey) 的等价写法
PHP的pack("H*")作用是把十六进制字符串解码成二进制数据,在Elixir里我们可以用Base.decode16!/2函数来实现。指定:case选项为:mixed的话,不管你的十六进制字符串是大写、小写还是混合大小写都能正常解码:
bin_key = Base.decode16!(hmac_key, case: :mixed)
小提示:如果你的十六进制字符串确定是纯大写或纯小写,也可以把
:case改成:upper或:lower;如果想优雅处理解码失败的情况,可以用Base.decode16/2(不带感叹号),它会返回{:ok, binary}或{:error, reason}的元组,方便你做错误处理。
2. hash_hmac('sha512', $msg, $binKey) + strtoupper() 的等价写法
PHP里这两步是生成SHA512的HMAC十六进制字符串,再转成大写。在Elixir中,我们先用Erlang标准库的:crypto.hmac/3生成二进制形式的HMAC,再用Base.encode16!/2转成大写的十六进制字符串,刚好对应PHP的逻辑:
hmac = :crypto.hmac(:sha512, bin_key, msg) |> Base.encode16!(case: :upper)
注:
:crypto是Erlang自带的模块,Elixir可以直接调用,它返回的是原始二进制数据,所以必须用Base.encode16!转成可读的十六进制格式,:upper参数就对应PHP的strtoupper()。
完整的Elixir等价代码
把上面两步整合起来,对应你给出的PHP代码,完整的Elixir实现可以写成一个函数:
defmodule HmacGenerator do def compute(hmac_key, msg) do bin_key = Base.decode16!(hmac_key, case: :mixed) :crypto.hmac(:sha512, bin_key, msg) |> Base.encode16!(case: :upper) end end # 调用示例: # HmacGenerator.compute("your_hex_hmac_key", "your_message_content")
额外补充:date("c") 的等价写法
你还提到了PHP的date("c"),它用来生成ISO 8601格式的日期字符串(比如2024-05-20T14:23:45+08:00)。在Elixir中,如果你需要当前UTC时间的ISO字符串,可以用:
DateTime.utc_now() |> DateTime.to_iso8601()
如果需要和PHP默认的本地时区一致,就换成获取本地时区的时间:
DateTime.now!(TimeZone.local()) |> DateTime.to_iso8601()
内容的提问来源于stack exchange,提问作者Hasimbola RAKOTOSON

