我在post请求中接收到一些数据,包括来自api的十进制数,并使用content-type:json。
在发布的数据中,有一个小数点4位的Amount参数。
{
"Amount": 500.0000 ,
"param1" : "value1" ,
"param2" : "value2"
}在解析json之后
$data = json_decode(file_get_contents('php://input'), true);
var_dump($data);这是我的输出
array(3) {
["Amount"]=>
float(500)
["param1"]=>
string(6) "value1"
["param2"]=>
string(6) "value2"
}问题是,如果小数位为零,我就会丢失小数位。
因此,我得到的不是500.0000,而是500,我知道它们在数学上是相同的,但是我需要从这些已发布的参数中生成一个散列,这就要求我将Amount作为一个浮点数,它的小数位数与第一位完全相同。
我可以这样做
$data['Amount'] = sprintf('%0.4f', $data['Amount'] );,而不是将其转换为字符串,这将导致无效的散列。
array(3) {
["Amount"]=>
string(8) "500.0000"
["param1"]=>
string(6) "value1"
["param2"]=>
string(6) "value2"
}我需要我的$data输出
["Amount"]=>
float(500.0000)试图运行它抛出浮点数,再次丢失小数点零!我正为这么简单的事情而发疯,知道怎么解决这个问题吗?
此散列的目的是验证请求的来源(确保是我的提供者发送数据给我)。
他们向我发送publicKey请求,我应该用一些参数生成哈希,并将其与那个公钥进行比较。
为了创建哈希,我需要json_encode一些接收到的参数并运行它们抛出sha256,最后我需要将它们与接收到的public_key进行比较。
所以如果我收到
{
"Amount": 5000.0000,
"Token": "6789",
"OperatorId": 7799,
"TransactionId": 110883669553,
"PublicKey": "f7bb8448c5701b9530fbecc8f9d6296b2ce0600118c402213709bcf19f533c1b"
}我就是这样计算散列的
$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
{"WithdrawAmount":5000.0000,"TransactionId":12345 }someKey如果它变成
{"WithdrawAmount":"5000.0000","TransactionId":12345 }someKey它会给我一个错误的哈希
发布于 2021-10-24 08:05:13
如前所述,在JSON字符串中没有直接格式化浮点值的方法。
作为Claudio的答案中显示的替换技术的替代方法,下面是一个简单的实用程序类,它帮助构建具有所需格式的JSON字符串:
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) . '}';
}
}示例:
$b = new JSONBuilder();
$b->add('Amount', 5000.0, '%0.4f');
$b->add('Token', '6789');
$b->add('TransactionId', 12345);
echo $b->get();输出:
{"Amount":5000.0000,"Token":"6789","TransactionId":12345}发布于 2021-10-22 16:59:39
我不认为有一种简单的方法可以执行一个浮点值的json_encode,当这个数字的小数部分是"0000“时,它要求小数4位,而不需要操作json字符串。
json_enconde方法有两个预定义的常量,它帮助我们“几乎”达到所需的结果,这些是分馏,但通常情况下,0被删除。
echo json_encode(["amount" => "5.0000"], JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION);产出:{"amount":5.0}
我的解决方案是使用一个惟一的字符串作为金额值执行编码,然后使用str_replace替换它,格式如下所示:
$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 ;发布于 2021-10-20 02:34:34
在C#中,您可以使用decimal类型而不是double或float来完成此操作。虽然我的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/
https://stackoverflow.com/questions/69639494
复制相似问题