cJson解析与base64解码的原型验证
base64.h
#ifndef _BASE64_H
#define _BASE64_H#include <stdint.h>
int bin_to_b64_nopad(const uint8_t * in, int size, char * out, int max_len);
int b64_to_bin_nopad(const char * in, int size, uint8_t * out, int max_len);
int bin_to_b64(const uint8_t * in, int size, char * out, int max_len);
int b64_to_bin(const char * in, int size, uint8_t * out, int max_len);#endif
cJSON.h
#ifndef cJSON__h
#define cJSON__h#ifdef __cplusplus
extern "C"
{
#endif/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
/*提供一个JSON块,然后返回一个可以查询的cJSON对象。完成后调用cJSON_Delete。*/
extern cJSON *cJSON_Parse(const char *value);/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
/*将cJSON实体呈现为用于传输/存储的文本。完成后释放char*。*/
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
/* Delete a cJSON entity and all subentities. */
/*删除一个cJSON实体和所有子实体。*/
extern void cJSON_Delete(cJSON *c);/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);/* These utilities create an Array of count items. */
/*这些共用工具创建 一些 对象*/
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
extern void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object *//* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
/*将对项的引用追加到指定的数组/对象。当您想要将现有的cJSON添加到新的cJSON中,但又不想破坏现有的cJSON时,可以使用此方法。*/
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);/* Remove/Detach items from Arrays/Objects. */
/*从数组/对象中删除/分离项*/
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
/*更新数组项*/
extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem); /* Shifts pre-existing items to the right. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);/* Duplicate a cJSON item */
/*复制一个cJSON对象*/
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. *//* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/*ParseWithOpts允许您要求(并检查)JSON是否为null终止,并检索指向解析后的最终字节的指针。*/
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);/*minify 使变小 削减*/
extern void cJSON_Minify(char *json);
/* Macros for creating things quickly. */
/*用于快速创建内容的宏。*/
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
/*在分配整数值时,也需要将其传播到valuedouble*/
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#define cJSON_SetNumberValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))#ifdef __cplusplus
}
#endif#endif
//注意:绿色标记的声明是用来进行解析Json格式的,其他的函数是用来封装Json格式的。
json_up (要解析的Json文件)
{
"rxpk": [{
"tmst": 66317107,
"chan": 2,
"rfch": 1,
"freq": 471.500000,
"stat": 1,
"modu": "LORA",
"datr": "SF7BW125",
"codr": "4/5",
"lsnr": 9.2,
"rssi": 3,
"size": 15,
"data": "QAEAAAAABQACSnK5CpM9"
}]
}40 01 00 00 00 00 05 00 02 4A 72 B9 0A 93 3D
mainTest.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h> /* strlen */
#include "cJSON.h"
#include "base64.h"
using namespace std;/* Parse text to JSON, then render back to text, and print! */
void doit(char *text)
{
char *out; cJSON *json; //要进行释放json = cJSON_Parse(text);
if (!json) { printf("Error before: [%s]\n", cJSON_GetErrorPtr()); }
else
{
out = cJSON_Print(json);
cJSON_Delete(json);
printf("%s\n", out);
free(out);
}
}int parse_up(char *parse_data) {
uint8_t outBuf[256];
memset(outBuf, 0, sizeof outBuf);//1.打包Json字符串
cJSON *cjson = cJSON_Parse(parse_data);
//1.1.判断是否打包成功
if (cjson == NULL) {
printf("cjson parse data error…");
exit(0);
}
//3.获取数组对象 cJSON_GetObjectItem
cJSON *rxpk = cJSON_GetObjectItem(cjson, "rxpk");//4.获取数组对象个数便于循环
int arr_size = cJSON_GetArraySize(rxpk); //return arr_size 1//5.获取test_arr数组对象孩子节点
cJSON* arr_item = rxpk->child;//子对象//6.循环获取数组下每个字段的值并使用cJSON_Print打印
cJSON *tmst = cJSON_GetObjectItem(arr_item, "tmst");
printf("tmst=%d\n", tmst->valueint);
cJSON *datr = cJSON_GetObjectItem(arr_item, "datr");
printf("datr=%s\n", datr->valuestring);
cJSON *data = cJSON_GetObjectItem(arr_item, "data");
printf("data=%s\n", data->valuestring);//进行解码操作
const char *str = (const char*)(data->valuestring);
int len = strlen(data->valuestring);
cout << "str=" << str << " " << "len=" << len << endl;int ret=b64_to_bin((const char*)(data->valuestring), strlen(data->valuestring), outBuf, sizeof outBuf);
if (ret == 0) {
printf("base64解密失败!\n");
return 0;
}
//printf("De_outBuf=%x\n",outBuf);
//cout << "De_outBuf[]=" << outBuf << endl;
unsigned int outBuf_len = strlen((const char *)outBuf);
cout << "outBuf_len= "<<outBuf_len << endl;
for (unsigned int m = 0; m < outBuf_len; m++) {
printf("%#x ", outBuf[m]);
}
printf("\n\n");
for (int m = 0; m < 20; m++) {
printf("%#x ", outBuf[m]);
}
//arr_item = arr_item->next;//下一个子对象
return 0;
}/* Read a file, parse, render back, etc. */
void dofile_up(const char *filename)
{
FILE *f; long len; char *data;f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);data = (char*)malloc(len + 1);
fread(data, 1, len, f);
fclose(f);doit(data);
//解析data数据
parse_up(data);free(data);
}
int main(int argc, const char * argv[]) {
/* Parse standard testfiles: */
dofile_up("json_up");system("pause");
return 0;
}
运行结果:
test6
{
"test_1": "1",
"test_2": "2",
"test_arr": [{"test_1": "arr_1",
"test_2": "arr_2",
"test_3": "arr_3"
},
{
"test_1": "1",
"test_2": "2",
"test_3": "3"
}
],
"test_3": "3"
}
ceshi_test6.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h> /* strlen */
#include "cJSON.h"
#include "base64.h"
using namespace std;/* Parse text to JSON, then render back to text, and print! */
void doit(char *text)
{
char *out; cJSON *json;json = cJSON_Parse(text);
if (!json) { printf("Error before: [%s]\n", cJSON_GetErrorPtr()); }
else
{
out = cJSON_Print(json);
cJSON_Delete(json);
printf("%s\n", out);
free(out);
}
}int parse_up(char *parse_data) {
//第一步打包JSON字符串
cJSON* cjson = cJSON_Parse(parse_data);//判断是否打包成功
if (cjson == NULL) {
printf("cjson error…");
}
//获取数组对象
cJSON* test_arr = cJSON_GetObjectItem(cjson, "test_arr");//获取数组对象个数便于循环
int arr_size = cJSON_GetArraySize(test_arr);//return arr_size 2
cout << arr_size << endl;
//获取test_arr数组对象孩子节点
cJSON* arr_item = test_arr->child;//子对象//循环获取数组下每个字段的值并使用cJSON_Print打印
for (int i = 0; i <= (arr_size - 1)/*0*/; ++i) {
char *out = cJSON_Print(cJSON_GetObjectItem(arr_item, "test_1"));
printf("%s\n", out);free(out);out = cJSON_Print(cJSON_GetObjectItem(arr_item, "test_2"));
printf("%s\n", out); free(out);
out = cJSON_Print(cJSON_GetObjectItem(arr_item, "test_3"));
printf("%s\n", out); free(out);arr_item = arr_item->next;//下一个子对象
}//获取“test_1” “test_2” “test_3”
cJSON *test_3 = cJSON_GetObjectItem(cjson, "test_3");
printf("test_3 : %s\n",test_3->valuestring);cJSON *test_2 = cJSON_GetObjectItem(cjson, "test_2");
printf("test_2 : %s\n", test_2->valuestring);//delete cjson 这里只需要释放cjson即可,因为其它的都指向它
cJSON_Delete(cjson);
return 0;
}
/* Read a file, parse, render back, etc. */
void dofile_up(const char *filename)
{
FILE *f; long len; char *data;f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);data = (char*)malloc(len + 1);
fread(data, 1, len, f);
fclose(f);doit(data);
//解析data数据
parse_up(data);free(data);
}
int main(int argc, const char * argv[]) {
dofile_up("test6");
system("pause");
return 0;
}
运行结果: