本文整理汇总了C++中HMAC_Init_ex函数的典型用法代码示例。如果您正苦于以下问题:C++ HMAC_Init_ex函数的具体用法?C++ HMAC_Init_ex怎么用?C++ HMAC_Init_ex使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了HMAC_Init_ex函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: main
int main(int argc, char *argv[]) {
if(argc != 2) {
printf("Usage: ./test_app <file_name>\n");
return -1;
}
ENGINE *e = load_engine(ENGINE_MODULE, "test_engine");
if(e == 0) {
printf("Unable to load engine\n");
return -1;
}
ENGINE_ctrl_cmd_string(e, "username", "user", 0);
ENGINE_ctrl_cmd_string(e, "password", "password", 0);
ENGINE_init(e);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, "test_key\0", 9, EVP_sha1(), e);
FILE *f = fopen(argv[1], "r");
char buf[BUF_SIZE];
while(!feof(f)) {
size_t ln = fread(buf, sizeof(char), BUF_SIZE, f);
if(ln == 0) continue;
HMAC_Update(&ctx, buf, ln);
}
fclose(f);
unsigned int siglen;
unsigned char md[20];
HMAC_Final(&ctx, md, &siglen);
ENGINE_finish(e);
printf("HMAC-SHA1: ");
for(size_t i = 0; i < siglen; i++) printf("%02x", md[i]);
printf("\n");
return 0;
}
开发者ID:GarysRefererence2014,项目名称:vhsm,代码行数:39,代码来源:test_app.c
示例2: init
void init(RC4_KEY* rc4, const unsigned char* session_key, const unsigned char* peer_key)
{
HMAC_CTX hmac_ctx;
HMAC_CTX_init(&hmac_ctx);
HMAC_Init_ex(&hmac_ctx, (void*)peer_key, peer_key_size, EVP_sha1(), NULL);
HMAC_Update(&hmac_ctx, session_key, session_key_size);
unsigned char rc4_keystring[SHA_DIGEST_LENGTH];
unsigned int rc4_keystring_size = SHA_DIGEST_LENGTH;
HMAC_Final(&hmac_ctx, rc4_keystring, &rc4_keystring_size);
HMAC_CTX_cleanup(&hmac_ctx);
RC4_set_key(rc4, rc4_keystring_size, rc4_keystring);
const unsigned char rc4_key_init[rc4_init_size] = { 0x00 };
unsigned char rc4_key_init_output[rc4_init_size];
RC4(rc4, sizeof(rc4_key_init), rc4_key_init, rc4_key_init_output);
}
开发者ID:HearthSim,项目名称:weave,代码行数:22,代码来源:WeaveCrypt.cpp
示例3: dsa_init
int
dsa_init(struct iked_dsa *dsa, const void *buf, size_t len)
{
int ret;
if (dsa->dsa_hmac) {
if (!HMAC_Init_ex(dsa->dsa_ctx, ibuf_data(dsa->dsa_keydata),
ibuf_length(dsa->dsa_keydata), dsa->dsa_priv, NULL))
return (-1);
return (0);
}
if (dsa->dsa_sign)
ret = EVP_SignInit_ex(dsa->dsa_ctx, dsa->dsa_priv, NULL);
else {
if ((ret = _dsa_verify_init(dsa, buf, len)) != 0)
return (ret);
ret = EVP_VerifyInit_ex(dsa->dsa_ctx, dsa->dsa_priv, NULL);
}
return (ret ? 0 : -1);
}
开发者ID:jymigeon,项目名称:openiked,代码行数:22,代码来源:crypto.c
示例4: cmeHMACInit
int cmeHMACInit (HMAC_CTX **ctx, ENGINE *engine, EVP_MD *digest, const char *key, int keyLen)
{
int result;
*ctx=(HMAC_CTX *)malloc(sizeof(HMAC_CTX));
HMAC_CTX_init(*ctx); //Initialize HMAC context.
result= HMAC_Init_ex(*ctx,key,keyLen,digest,engine);
if (result==0) //1= success, 0=failure
{
#ifdef ERROR_LOG
fprintf(stderr,"CaumeDSE Error: cmeHMACInit(), HMAC_Init_ex() failure!\n");
#endif
return (1);
}
else
{
#ifdef DEBUG
fprintf(stdout,"CaumeDSE Debug: cmeHMACInit(), HMAC_Init_ex() success.\n");
#endif
return (0);
}
开发者ID:xtremebeing,项目名称:CaumeDSE,代码行数:21,代码来源:crypto.c
示例5: aead_tls_init
static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
size_t tag_len, enum evp_aead_direction_t dir,
const EVP_CIPHER *cipher, const EVP_MD *md,
char implicit_iv) {
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
tag_len != EVP_MD_size(md)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
size_t mac_key_len = EVP_MD_size(md);
size_t enc_key_len = EVP_CIPHER_key_length(cipher);
assert(mac_key_len + enc_key_len +
(implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len);
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state;
EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
HMAC_CTX_init(&tls_ctx->hmac_ctx);
assert(mac_key_len <= EVP_MAX_MD_SIZE);
OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len);
tls_ctx->mac_key_len = (uint8_t)mac_key_len;
tls_ctx->implicit_iv = implicit_iv;
if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len],
implicit_iv ? &key[mac_key_len + enc_key_len] : NULL,
dir == evp_aead_seal) ||
!HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) {
aead_tls_cleanup(ctx);
return 0;
}
EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0);
return 1;
}
开发者ID:wolfviking0,项目名称:webcl-webkit,代码行数:39,代码来源:e_tls.c
示例6: hmac_fdigest
static int hmac_fdigest(lua_State *L)
{
const char *t = luaL_checkstring(L, 1);
const EVP_MD *type = EVP_get_digestbyname(t);
const char *s;
const char *k;
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int written = 0;
unsigned int i;
char *hex;
HMAC_CTX c;
if (type == NULL) {
luaL_argerror(L, 1, "invalid digest type");
return 0;
}
s = luaL_checkstring(L, 2);
k = luaL_checkstring(L, 3);
HMAC_CTX_init(&c);
HMAC_Init_ex(&c, k, (int)lua_strlen(L, 3), type, NULL);
HMAC_Update(&c, (unsigned char *)s, lua_strlen(L, 2));
HMAC_Final(&c, digest, &written);
HMAC_CTX_cleanup(&c);
if (lua_toboolean(L, 4))
lua_pushlstring(L, (char *)digest, written);
else {
hex = (char*)calloc(sizeof(char), written*2 + 1);
for (i = 0; i < written; i++)
sprintf(hex + 2*i, "%02x", digest[i]);
lua_pushlstring(L, hex, written*2);
free(hex);
}
return 1;
}
开发者ID:ignacio,项目名称:luacrypto,代码行数:39,代码来源:lcrypto.c
示例7: calculate_auth_data
static int calculate_auth_data(const struct iovec *iov, int iovlen,
const struct in6_addr *coa,
const struct in6_addr *cn,
const uint8_t *key, uint8_t *digest)
{
uint8_t buf[HMAC_SHA1_HASH_LEN];
int i;
#ifdef HAVE_LIBCRYPTO
unsigned int len = HMAC_SHA1_HASH_LEN;
HMAC_CTX ctx;
const EVP_MD *evp_md = EVP_sha1();
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, HMAC_SHA1_KEY_SIZE, evp_md, NULL);
HMAC_Update(&ctx, (uint8_t *)coa, sizeof(*coa));
HMAC_Update(&ctx, (uint8_t *)cn, sizeof(*coa));
for (i = 0; i < iovlen; i++) {
HMAC_Update(&ctx, (uint8_t *)iov[i].iov_base, iov[i].iov_len);
}
HMAC_Final(&ctx, buf, &len);
HMAC_CTX_cleanup(&ctx);
#else
HMAC_SHA1_CTX ctx;
HMAC_SHA1_init(&ctx, key, HMAC_SHA1_KEY_SIZE);
HMAC_SHA1_update(&ctx, (uint8_t *)coa, sizeof(*coa));
HMAC_SHA1_update(&ctx, (uint8_t *)cn, sizeof(*coa));
for (i = 0; i < iovlen; i++) {
HMAC_SHA1_update(&ctx, (uint8_t *)iov[i].iov_base,
iov[i].iov_len);
}
HMAC_SHA1_final(&ctx, buf);
#endif
memcpy(digest, buf, MIPV6_DIGEST_LEN);
return 0;
}
开发者ID:NetworkingGroupSKKU,项目名称:Buffering-Scheme-in-PMIPv6,代码行数:38,代码来源:mh.c
示例8: PKI_HMAC_init
/*
* \brief Initializes the passed hmac to use the passed key and digest algorithm
*/
int PKI_HMAC_init(PKI_HMAC *hmac, unsigned char *key, size_t key_size, PKI_DIGEST_ALG *digest, HSM *hsm)
{
if (!hmac) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
// Free the memory if another key was used
if (hmac->key) PKI_MEM_free(hmac->key);
hmac->key = NULL;
if (hmac->value) PKI_MEM_free(hmac->value);
hmac->value = NULL;
// Generate the new PKI_MEM to hold the key data
hmac->key = PKI_MEM_new_data(key_size, key);
if (!hmac->key || !hmac->key->data || hmac->key->size <= 0)
{
hmac->initialized = 0;
return PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
}
// Sets the algoritm
hmac->digestAlg = digest ? digest : PKI_DIGEST_ALG_SHA1;
// Checks if HSM implementation was asked by the developer
if (hsm)
{
PKI_ERROR(PKI_ERR_GENERAL, "Code to support HMAC on HSMs not implemented, yet.");
hmac->initialized = 0;
return PKI_ERR;
}
// Initializes the Context
HMAC_Init_ex(&hmac->ctx, (const void *) key, (int) key_size, hmac->digestAlg, NULL);
// Sets the initialization flag
hmac->initialized = 1;
return PKI_OK;
}
开发者ID:Brenhilt,项目名称:libpki,代码行数:41,代码来源:pki_hmac.c
示例9: HmacMd5Init
/**
Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for
subsequent use.
If HmacMd5Context is NULL, then return FALSE.
@param[out] HmacMd5Context Pointer to HMAC-MD5 context being initialized.
@param[in] Key Pointer to the user-supplied key.
@param[in] KeySize Key size in bytes.
@retval TRUE HMAC-MD5 context initialization succeeded.
@retval FALSE HMAC-MD5 context initialization failed.
**/
BOOLEAN
EFIAPI
HmacMd5Init (
OUT VOID *HmacMd5Context,
IN CONST UINT8 *Key,
IN UINTN KeySize
)
{
//
// Check input parameters.
//
if (HmacMd5Context == NULL || KeySize > INT_MAX) {
return FALSE;
}
//
// OpenSSL HMAC-MD5 Context Initialization
//
HMAC_CTX_init (HmacMd5Context);
HMAC_Init_ex (HmacMd5Context, Key, (UINT32) KeySize, EVP_md5(), NULL);
return TRUE;
}
开发者ID:Acidburn0zzz,项目名称:shim,代码行数:37,代码来源:CryptHmacMd5.c
示例10: hmac_fnew
static int hmac_fnew(lua_State *L)
{
HANDLER_HMAC *c = hmac_pnew(L);
const char *s = luaL_checkstring(L, 1);
size_t k_len;
const char *k = luaL_checklstring(L, 2, &k_len);
DIGEST_TYPE type = DIGEST_BY_NAME(s);
if (IS_DIGEST_INVALID(type)) {
luaL_argerror(L, 1, "invalid digest type");
return 0;
}
#if CRYPTO_OPENSSL
HMAC_CTX_init(c);
HMAC_Init_ex(c, k, k_len, type, NULL);
#elif CRYPTO_GCRYPT
gcry_md_open(c, type, GCRY_MD_FLAG_HMAC);
gcry_md_setkey(*c, k, k_len);
#endif
return 1;
}
开发者ID:hahnakane,项目名称:junkcode,代码行数:23,代码来源:lcrypto.c
示例11: fr_hmac_md5
/** Calculate HMAC using OpenSSL's MD5 implementation
*
* @param digest Caller digest to be filled in.
* @param in Pointer to data stream.
* @param inlen length of data stream.
* @param key Pointer to authentication key.
* @param key_len Length of authentication key.
*
*/
void fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
uint8_t const *key, size_t key_len)
{
HMAC_CTX *ctx;
if (unlikely(!md5_hmac_ctx)) {
ctx = HMAC_CTX_new();
if (unlikely(!ctx)) return;
fr_thread_local_set_destructor(md5_hmac_ctx, _hmac_md5_ctx_free_on_exit, ctx);
} else {
ctx = md5_hmac_ctx;
}
#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
/* Since MD5 is not allowed by FIPS, explicitly allow it. */
HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
#endif /* EVP_MD_CTX_FLAG_NON_FIPS_ALLOW */
HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL);
HMAC_Update(ctx, in, inlen);
HMAC_Final(ctx, digest, NULL);
HMAC_CTX_reset(ctx);
}
开发者ID:FreeRADIUS,项目名称:freeradius-server,代码行数:32,代码来源:hmac_md5.c
示例12: malloc
char* CryptoHandler::hmac_sha512(char* datain, char* keyin, const bool& base64)
{
unsigned char* key = (unsigned char*) keyin;
unsigned char* data = (unsigned char*) datain;
unsigned char* result;
unsigned int result_len = 64;
HMAC_CTX ctx;
result = (unsigned char*) malloc(sizeof(char) * result_len);
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, strlen(keyin), EVP_sha512(), NULL);
HMAC_Update(&ctx, data, strlen(datain));
HMAC_Final(&ctx, result, &result_len);
HMAC_CTX_cleanup(&ctx);
if(base64)
return base64encode(result,result_len);
return (char*)result;
}
开发者ID:GYGit,项目名称:ffead-cpp,代码行数:23,代码来源:CryptoHandler.cpp
示例13: HmacSha1Init
/**
Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for
subsequent use.
If HmacSha1Context is NULL, then return FALSE.
@param[out] HmacSha1Context Pointer to HMAC-SHA1 context being initialized.
@param[in] Key Pointer to the user-supplied key.
@param[in] KeySize Key size in bytes.
@retval TRUE HMAC-SHA1 context initialization succeeded.
@retval FALSE HMAC-SHA1 context initialization failed.
**/
BOOLEAN
EFIAPI
HmacSha1Init (
OUT VOID *HmacSha1Context,
IN CONST UINT8 *Key,
IN UINTN KeySize
)
{
//
// Check input parameters.
//
if (HmacSha1Context == NULL) {
return FALSE;
}
//
// OpenSSL HMAC-SHA1 Context Initialization
//
HMAC_CTX_init (HmacSha1Context);
HMAC_Init_ex (HmacSha1Context, Key, (UINT32) KeySize, EVP_sha1(), NULL);
return TRUE;
}
开发者ID:etiago,项目名称:vbox,代码行数:37,代码来源:CryptHmacSha1.c
示例14: mac_init
int
mac_init(Mac *mac)
{
if (mac->key == NULL)
fatal("mac_init: no key");
switch (mac->type) {
case SSH_EVP:
if (mac->evp_md == NULL)
return -1;
#ifdef HAVE_HMAC_CTX_INIT
HMAC_CTX_init(&mac->evp_ctx);
HMAC_Init_ex(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md, NULL);
#else
HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md);
#endif
return 0;
case SSH_UMAC:
mac->umac_ctx = umac_new(mac->key);
return 0;
default:
return -1;
}
}
开发者ID:msftguy,项目名称:openssh-sc,代码行数:23,代码来源:mac.c
示例15:
unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
const unsigned char *d, size_t n, unsigned char *md,
unsigned int *md_len)
{
HMAC_CTX *c = NULL;
static unsigned char m[EVP_MAX_MD_SIZE];
if (md == NULL)
md = m;
if ((c = HMAC_CTX_new()) == NULL)
goto err;
if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
goto err;
if (!HMAC_Update(c, d, n))
goto err;
if (!HMAC_Final(c, md, md_len))
goto err;
HMAC_CTX_free(c);
return md;
err:
HMAC_CTX_free(c);
return NULL;
}
开发者ID:AndreV84,项目名称:openssl,代码行数:23,代码来源:hmac.c
示例16: qHMAC512
extern "C" K qHMAC512(K data, K key)
{
unsigned int SHA512_DIGEST_LENGTH=64;
unsigned char md[SHA512_DIGEST_LENGTH];
unsigned char result[SHA512_DIGEST_LENGTH];
unsigned int len=0;
K ret = ktn(KG,SHA512_DIGEST_LENGTH);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key->s, strlen(key->s), EVP_sha512(), NULL);
HMAC_Update(&ctx, (unsigned char*)(data->s), strlen(data->s));
HMAC_Final(&ctx, result, &len);
HMAC_CTX_cleanup(&ctx);
for(int i=0; i < len ; i++)
kG(ret)[i]=result[i];
return (ret);
}
开发者ID:nunb,项目名称:btceQ,代码行数:24,代码来源:hmac512.cpp
示例17: writeChunk
static void writeChunk(FileVaultInfo* info) {
unsigned char buffer[info->blockSize];
unsigned char buffer2[info->blockSize];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
uint32_t myChunk;
myChunk = info->curChunk;
FLIPENDIAN(myChunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (unsigned char *) &myChunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(info->chunk, buffer, info->blockSize, &(info->aesEncKey), msgDigest, AES_ENCRYPT);
info->file->seek(info->file, (info->curChunk * info->blockSize) + info->dataOffset);
info->file->read(info->file, buffer2, info->blockSize);
info->file->seek(info->file, (info->curChunk * info->blockSize) + info->dataOffset);
info->file->write(info->file, buffer, info->blockSize);
info->dirty = FALSE;
}
开发者ID:Accusedbold,项目名称:shoes,代码行数:24,代码来源:filevault.c
示例18: srp_init_hmac
static int
srp_init_hmac(
HMAC_CTX *phctx,
unsigned char *key,
int key_len)
{
int sts = 0;
HMAC_CTX hctx;
unsigned char md[40] = {0};
unsigned int mdlen = 0;
memset(&hctx, 0, sizeof(hctx));
HMAC_CTX_init(&hctx);
sts = HMAC_Init_ex(&hctx, key, key_len, EVP_sha1(), NULL);
if (sts == 0)
{
return sts;
}
HMAC_Update(&hctx, "", 0);
HMAC_Final(&hctx, md, &mdlen);
*phctx = hctx;
return 0;
}
开发者ID:DhanashreeA,项目名称:lightwave,代码行数:24,代码来源:unix_encrypt.c
示例19: hash
void hash(char data[]) {
// The secret key for hashing
const char key[] = "12345678";
// The data that we're going to hash
//char data[] = "hello world";
// Be careful of the length of string with the choosen hash engine. SHA1 needed 20 characters.
// Change the length accordingly with your choosen hash engine.
unsigned char* result;
unsigned int len = 20;
result = (unsigned char*)malloc(sizeof(char) * len);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
// Using sha1 hash engine here.
// You may use other hash engines. e.g EVP_md5(), EVP_sha224, EVP_sha512, etc
HMAC_Init_ex(&ctx, key, strlen(key), EVP_sha1(), NULL);
// HMAC_Update(&ctx, (unsigned char*)&data, strlen(data));
HMAC_Final(&ctx, result, &len);
HMAC_CTX_cleanup(&ctx);
printf("HMAC digest: ");
for (int i = 0; i != len; i++)
printf("%02x", (unsigned int)result[i]);
printf("\n");
//free(result);
}
开发者ID:sagarjawanjal93,项目名称:hashCodeTLSAuthentication,代码行数:36,代码来源:SSl-Server.c
示例20: PKCS12_gen_mac
/* Generate a MAC */
int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *mac, unsigned int *maclen)
{
const EVP_MD *md_type;
HMAC_CTX hmac;
unsigned char key[PKCS12_MAC_KEY_LENGTH], *salt;
int saltlen, iter;
if (!PKCS7_type_is_data(p12->authsafes))
{
PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_CONTENT_TYPE_NOT_DATA);
return 0;
}
salt = p12->mac->salt->data;
saltlen = p12->mac->salt->length;
if (!p12->mac->iter) iter = 1;
else iter = ASN1_INTEGER_get (p12->mac->iter);
if(!(md_type =
EVP_get_digestbyobj (p12->mac->dinfo->algor->algorithm))) {
PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
return 0;
}
if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
PKCS12_MAC_KEY_LENGTH, key, md_type)) {
PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR);
return 0;
}
HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, key, PKCS12_MAC_KEY_LENGTH, md_type, NULL);
HMAC_Update(&hmac, p12->authsafes->d.data->data,
p12->authsafes->d.data->length);
HMAC_Final(&hmac, mac, maclen);
HMAC_CTX_cleanup(&hmac);
return 1;
}
开发者ID:yyyyyao,项目名称:Slicer3-lib-mirrors,代码行数:37,代码来源:p12_mutl.c
注:本文中的HMAC_Init_ex函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论