- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
好吧,我一直在尝试重现这个 PHP 脚本的功能:
<?php
function api_query($method, array $req = array()) {
// API settings
$key = ''; // your API-key
$secret = ''; // your Secret-key
$req['method'] = $method;
$mt = explode(' ', microtime());
$req['nonce'] = $mt[1];
// generate the POST data string
$post_data = http_build_query($req, '', '&');
$sign = hash_hmac("sha512", $post_data, $secret);
// generate the extra headers
$headers = array(
'Sign: '.$sign,
'Key: '.$key,
);
// our curl handle (initialize if required)
static $ch = null;
if (is_null($ch)) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; Cryptsy API PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
}
curl_setopt($ch, CURLOPT_URL, 'https://www.cryptsy.com/api');
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// run the query
$res = curl_exec($ch);
if ($res === false) throw new Exception('Could not get reply: '.curl_error($ch));
$dec = json_decode($res, true);
if (!$dec) throw new Exception('Invalid data received, please make sure connection is working and requested API exists');
return $dec;
}
我已经(至少我相信我已经)通过自己构建查询来创建 C 所没有的 http_build_query 调用。我通过使用 gettimeofday() 在 mtStr 中拥有 $mt 变量,并且使用 openSSL 中的 HMAC 函数用我的 key 对 post_data 进行签名。
我发现C中的CURLOPT_HTTPHEADER选项需要一个curl_slist链接列表,而不仅仅是像PHP中的数组,但我似乎遇到问题的是在发布数据中。请求将通过,但会返回一个错误,提示“检查您的 POST 数据”。所以我回到 libcurl 文档,发现 CURLOPT_POSTFIELDS 需要一个 void* 来发送您想要发布的数据。所以我创建了 void *pData = post_data (其中 post_data 只是一个字符数组,而不是指针,所以我在这里没有看到探针),但它仍然说它无法验证我的身份,请检查 POST 数据。因此,如果您能看一下这个并告诉我哪里出错了,我将不胜感激......
请注意,我没有显示我的 API 和 key ,因为我无法自己更改它们,我宁愿不透露它们,但我知道这使得在没有加密帐户的情况下很难通过自己编译来检查我的东西,但我现在想保密,但里面有一些虚拟 key ,这样就可以对长度合适的哈希值等进行哈希处理。
char *handle_url( char *url )
{
CURL *curl;
struct url_data data;
data.size = 0;
data.data = malloc( 4096 );
if ( NULL == data.data )
{
fprintf( stderr, "failed to allocate memory.\n" );
return NULL;
}
data.data[0] = '\0';
CURLcode res;
// API settings, API key and secret key for your account
char key[] = "9498fbb723961a42816a10bc559cgda7ded2ed8e";
char secret[] = "687cd29def08a7861446c3b4b9c97996c8472e7dd8922da147d3b1343e52e99125d24ace90729fbb";
// method to use against the API, will make changable later
char *method = "mytrades";
// This is required to replace the microtime()/explode methods to
// generate the nonce value required to use the cryptsy API
struct timeval time;
gettimeofday( &time, NULL );
long mt = ( (unsigned long long)time.tv_sec * 1000000 ) + time.tv_usec;
// C is much morer strict than PHP about types so we create a buffer for the
// string representation of the nonce
char mtStr[ 128 ];
sprintf( mtStr, "%lu", mt );
// C does not have a build_http_query as PHP does so
// we just create the string neccessary with strcpy
// and strcat
char post_data[ strlen("method=") + strlen(method) + strlen("&nonce=") + strlen(mtStr) + 1];
strcpy( post_data, "method=" );
strcat( post_data, method );
strcat( post_data, "&" );
strcat( post_data, "nonce=" );
strcat( post_data, mtStr );
printf( "%s", post_data);
printf( "\n");
void *pData = post_data;
//sha512 needs 128 characters
unsigned char *result;
unsigned int len = 128;
result = (unsigned char *)malloc( sizeof(char) * len );
HMAC_CTX ctx;
HMAC_CTX_init( &ctx );
// using sha512
HMAC_Init_ex( &ctx, secret, strlen(secret), EVP_sha512(), NULL );
HMAC_Update( &ctx, (unsigned char *)&post_data, strlen(post_data) );
HMAC_Final( &ctx, result, &len );
HMAC_CTX_cleanup( &ctx );
/*
printf( "\nHMAC digest: " );
for ( int i = 0; i != len; i++ )
{
printf( "%02x", (unsigned int)result[i] );
} */
printf("\n");
// This is the start of setting up the $headers array as in the PHP script
const char *header1 = "Sign: ";
size_t PrefixL = strlen(header1);
char resBuffer[PrefixL + 2 * len + 1];
strcpy( resBuffer, header1);
char *p = &resBuffer[PrefixL];
for ( unsigned int i = 0; i < len; i++ )
{
sprintf( p, "%02x", (unsigned int)result[i]);
p += 2;
}
printf( "%s\n", resBuffer );
const char *header2 = "Key: ";
size_t PrefixR = strlen(header2);
char keyBuffer[PrefixR + 2 * strlen(key) + 1];
strcpy( keyBuffer, header2);
strcat( keyBuffer, key);
printf( "\n%s\n", keyBuffer );
// So now resBuffer is Sign: <128 character sha512 hash here>
// and keyBuffer is Key: <API key here>
free(result);
//struct curl_httppost *chttppostlist = NULL; //a possibility about sending chunked post data not currently used
// originally I set this up so that Sign and Key would be in the array in the same
// manner as the PHP script but libcurl in C needs a curl_slist
const char *headerArray[2];
headerArray[0] = resBuffer;
headerArray[1] = keyBuffer;
// So then we just create a curl_slist and add the resBuffer and keyBuffer (headerArray
// [0] and headerArray[1] respectively) to the curl_slist.
struct curl_slist *cslist= NULL;
curl_slist_append(cslist, headerArray[0]);
curl_slist_append(cslist, headerArray[1]);
curl = curl_easy_init();
if ( curl )
{
curl_easy_setopt( curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible Cryptsy API C Client)");
curl_easy_setopt( curl, CURLOPT_URL, url );
curl_easy_setopt( curl, CURLOPT_POST, 1 ); // is this necessary? isnt in PHP
curl_easy_setopt( curl, CURLOPT_POSTFIELDS, pData ); // <--- something wrong here?
curl_easy_setopt( curl, CURLOPT_HTTPHEADER, cslist );
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_data );
curl_easy_setopt( curl, CURLOPT_WRITEDATA, &data );
curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 0 );
res = curl_easy_perform( curl );
if ( res != CURLE_OK )
{
fprintf( stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_slist_free_all( cslist );
curl_easy_cleanup( curl );
}
return data.data;
}
最佳答案
#include <iostream>
#include <cstdlib>
#include <cstring>
#include "json_parsers.h"
extern "C" {
#include <curl/curl.h>
#include <sys/time.h>
#include <limits.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
}
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
using namespace std;
struct url_data {
size_t size;
char *data;
};
size_t write_data( void *ptr, size_t size, size_t nmemb, struct url_data *data )
{
size_t index = data->size;
size_t n = ( size * nmemb );
char *tmp;
data->size += ( size * nmemb );
#ifdef DEBUG
fprintf( stderr, "data at %p size=%ld nmemb=%ld\n", ptr,
size, nmemb );
#endif
tmp = (char *)realloc( data->data, data->size + 1); // + 1 for \n
if ( tmp )
{
data->data = tmp;
}
else
{
if ( data->data )
{
free( data->data );
}
fprintf( stderr, "Failed to allocate memory.\n" );
return 0;
}
memcpy( ( data->data + index ), ptr, n );
data->data[ data->size ] = '\0';
return size * nmemb;
}
char *cryptsy_api( char *url, char *method_in, char *marketid, int limit, char *ordertype, char *quantity, char *price, char *orderid ) {
CURL *curl;
struct url_data data;
data.size = 0;
data.data = (char *)malloc(4096);
if (data.data == NULL)
{
cerr << "Failed to allocate memory.\n" << endl;
return NULL;
}
data.data[0] = '\0';
CURLcode res;
char strInt[5];
if (limit != NULL)
{
sprintf(strInt, "%d", limit);
}
// API settings, API key and secret key for your account
char key[] = "9498fbb723961a42816a10bc559cfda7ded2ed8f";
char secret[] = "687cd29def08a7861446c3b4b9c97996c8472e7dd8922da147d3b1346e52e99125d24ace90729fb3";
char *method = method_in;
// This is required to replace the microtime()/explode methods to
// generate the nonce value required to use the cryptsy API
struct timeval time;
gettimeofday(&time, NULL);
long mt = (unsigned long long)time.tv_sec;
char mtStr[10];
sprintf(mtStr, "%ul", mt);
// C does not have a build_http_query as PHP does so
// we just create the string neccessary with strcpy
// and strcat
char post_data[ strlen("method=") + strlen(method) + strlen("&nonce=") + strlen(mtStr) + strlen("&marketid=110") + strlen("&limit=1000") + strlen("&ordertype=sell&quantity=1000000&price=0.00000000")+ 1];
strcpy(post_data, "method=");
strcat(post_data, method);
strcat(post_data, "&nonce=");
strcat(post_data, mtStr);
if (marketid != NULL)
{
strcat(post_data, "&marketid=");
strcat(post_data, marketid);
}
if (limit != NULL)
{
strcat(post_data, "&limit=");
strcat(post_data, strInt);
}
if (ordertype != NULL)
{
strcat(post_data, "&ordertype=");
strcat(post_data, ordertype);
}
if (quantity != NULL)
{
strcat(post_data, "&quantity=");
strcat(post_data, quantity);
}
if (price != NULL)
{
strcat(post_data, "&price=");
strcat(post_data, price);
}
if (orderid != NULL)
{
strcat(post_data, "&orderid=");
strcat(post_data, orderid);
}
unsigned char *result;
unsigned int len = SHA512_DIGEST_LENGTH;
result = (unsigned char *)malloc(sizeof(char) * len);
HMAC_CTX ctx;
HMAC_CTX_init( &ctx );
// using SHA512
HMAC_Init_ex( &ctx, secret, strlen(secret), EVP_sha512(), NULL);
HMAC_Update( &ctx, (unsigned char *)&post_data, strlen(post_data));
HMAC_Final( &ctx, result, &len);
HMAC_CTX_cleanup( &ctx );
const char *header1 = "Sign: ";
size_t PrefixL = strlen(header1);
char resBuffer[PrefixL + 2 * len + 1];
strcpy(resBuffer, header1);
char *p = &resBuffer[PrefixL];
for (unsigned int i = 0; i < len; i++)
{
sprintf(p, "%02x", (unsigned int)result[i]);
p += 2;
}
const char *header2 = "Key: ";
size_t PrefixR = strlen(header2);
char keyBuffer[PrefixR + 2 * strlen(key) + 1];
strcpy(keyBuffer, header2);
strcat(keyBuffer, key);
free(result);
struct curl_slist *cslist = NULL;
cslist = curl_slist_append(cslist, resBuffer);
cslist = curl_slist_append(cslist, keyBuffer);
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible Cryptsy API C Client)");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(post_data));
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, cslist);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
cerr << "curl_easy_perform() failed " << curl_easy_strerror(res) << "\n" << endl;
}
curl_slist_free_all(cslist);
curl_easy_cleanup(curl);
}
return data.data;
}
抱歉无法格式化最后一位,但您明白了,是的,我更改了 API key :)
关于php - 使用/发送 POST 数据时的 libcurl C 问题(不是 C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20320605/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!