首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >强制在数字上小数4位,而不将其类型更改为字符串。

强制在数字上小数4位,而不将其类型更改为字符串。
EN

Stack Overflow用户
提问于 2021-10-20 02:05:21
回答 4查看 225关注 0票数 4

我在post请求中接收到一些数据,包括来自api的十进制数,并使用content-type:json

在发布的数据中,有一个小数点4位的Amount参数。

代码语言:javascript
复制
{
  "Amount": 500.0000  ,
  "param1" : "value1" ,
  "param2" : "value2" 
}

在解析json之后

代码语言:javascript
复制
$data = json_decode(file_get_contents('php://input'), true);
var_dump($data);

这是我的输出

代码语言:javascript
复制
array(3) {
  ["Amount"]=>
  float(500)
  ["param1"]=>
  string(6) "value1"
  ["param2"]=>
  string(6) "value2"
}

问题是,如果小数位为零,我就会丢失小数位。

因此,我得到的不是500.0000,而是500,我知道它们在数学上是相同的,但是我需要从这些已发布的参数中生成一个散列,这就要求我将Amount作为一个浮点数,它的小数位数与第一位完全相同。

我可以这样做

代码语言:javascript
复制
$data['Amount'] = sprintf('%0.4f',   $data['Amount'] );

,而不是将其转换为字符串,这将导致无效的散列。

代码语言:javascript
复制
array(3) {
  ["Amount"]=>
  string(8) "500.0000"
  ["param1"]=>
  string(6) "value1"
  ["param2"]=>
  string(6) "value2"
}

我需要我的$data输出

代码语言:javascript
复制
  ["Amount"]=>
  float(500.0000)

试图运行它抛出浮点数,再次丢失小数点零!我正为这么简单的事情而发疯,知道怎么解决这个问题吗?

此散列的目的是验证请求的来源(确保是我的提供者发送数据给我)。

他们向我发送publicKey请求,我应该用一些参数生成哈希,并将其与那个公钥进行比较。

为了创建哈希,我需要json_encode一些接收到的参数并运行它们抛出sha256,最后我需要将它们与接收到的public_key进行比较。

所以如果我收到

代码语言:javascript
复制
{
  "Amount": 5000.0000,
  "Token": "6789",
  "OperatorId": 7799,
  "TransactionId": 110883669553,
  "PublicKey": "f7bb8448c5701b9530fbecc8f9d6296b2ce0600118c402213709bcf19f533c1b"
}

我就是这样计算散列的

代码语言:javascript
复制
$shared_key  =  'someKey';
$hash_params = [
   'Amount'       => $data['Amount'] , 
   'TransactionId' => $data['TransactionId'] , 
];
$hash_string = json_encode($hash_params) . $shared_key ;
$hash =  hash('sha256',    $hash_string  );    
if($hash != $data['PublicKey'] )
{
    die( "hash check failed");
}

在这个场景中,我需要sha256这个$hash_string

代码语言:javascript
复制
{"WithdrawAmount":5000.0000,"TransactionId":12345 }someKey

如果它变成

代码语言:javascript
复制
{"WithdrawAmount":"5000.0000","TransactionId":12345 }someKey

它会给我一个错误的哈希

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-10-24 08:05:13

如前所述,在JSON字符串中没有直接格式化浮点值的方法。

作为Claudio的答案中显示的替换技术的替代方法,下面是一个简单的实用程序类,它帮助构建具有所需格式的JSON字符串:

代码语言:javascript
复制
class JSONBuilder
{
    private $params = [];

    public function add($name, $value, $format='')
    {
        if($format)
            $encoded = sprintf($format, $value);
        else
            $encoded = json_encode($value);
        $this->params[] = sprintf('"%s":%s', $name, $encoded);
    }

    public function get()
    {
        return '{' . join(',', $this->params) . '}';
    }
}

示例:

代码语言:javascript
复制
$b = new JSONBuilder();
$b->add('Amount', 5000.0, '%0.4f');
$b->add('Token', '6789');
$b->add('TransactionId', 12345);
echo $b->get();

输出:

代码语言:javascript
复制
{"Amount":5000.0000,"Token":"6789","TransactionId":12345}
票数 2
EN

Stack Overflow用户

发布于 2021-10-22 16:59:39

我不认为有一种简单的方法可以执行一个浮点值的json_encode,当这个数字的小数部分是"0000“时,它要求小数4位,而不需要操作json字符串。

json_enconde方法有两个预定义的常量,它帮助我们“几乎”达到所需的结果,这些是分馏,但通常情况下,0被删除。

代码语言:javascript
复制
echo json_encode(["amount" => "5.0000"], JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION);

产出:{"amount":5.0}

我的解决方案是使用一个惟一的字符串作为金额值执行编码,然后使用str_replace替换它,格式如下所示:

代码语言:javascript
复制
$amount_needle = "###amount###";
$hash_params = [
   'Amount'       => $amount_needle, 
   'TransactionId' => $data['TransactionId'], 
];
$encoded_json = json_encode($hash_params);
$hash_string = str_replace("\"{$amount_needle}\"", sprintf('%0.4f', $data['Amount']), $encoded_json) . $shared_key ;
票数 2
EN

Stack Overflow用户

发布于 2021-10-20 02:34:34

在C#中,您可以使用decimal类型而不是doublefloat来完成此操作。虽然我的PHP知识有限,但在BC和PHP中,PHP世界似乎有类似的东西。

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types https://www.php.net/manual/en/book.bc.php https://php-decimal.io/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69639494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档