当前位置: 首页>>代码示例>>C++>>正文


C++ EVP_aes_256_cbc函数代码示例

本文整理汇总了C++中EVP_aes_256_cbc函数的典型用法代码示例。如果您正苦于以下问题:C++ EVP_aes_256_cbc函数的具体用法?C++ EVP_aes_256_cbc怎么用?C++ EVP_aes_256_cbc使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了EVP_aes_256_cbc函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: CKeyingMaterial

bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
{
    if (!fKeySet)
        return false;

    // plaintext will always be equal to or lesser than length of ciphertext
    int nLen = vchCiphertext.size();
    int nPLen = nLen, nFLen = 0;

    vchPlaintext = CKeyingMaterial(nPLen);

    EVP_CIPHER_CTX ctx;

    bool fOk = true;

    EVP_CIPHER_CTX_init(&ctx);
    if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
    if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
    if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
    EVP_CIPHER_CTX_cleanup(&ctx);

    if (!fOk) return false;

    vchPlaintext.resize(nPLen + nFLen);
    return true;
}
开发者ID:cndengchina,项目名称:bitDump,代码行数:26,代码来源:crypter.cpp

示例2: encrypt_msg

/*
 * This function encrypts a string before calling send_msg.
 * It also append the given IV for the ecnryption mode.
 * It returns the length of the cipher text (iv is not considered), -1 on error.
 * Errno is set appropriately
 */
int encrypt_msg(int sk, char format, unsigned char* plain, unsigned int plain_len, unsigned char* shared_secret)
{
	EVP_CIPHER_CTX* ctx;
	unsigned char* iv;
	unsigned int iv_len = EVP_MAX_IV_LENGTH;
	unsigned char* outbuf = NULL;
	int outlen, outtot = 0;
	ctx = (EVP_CIPHER_CTX*)calloc(1, sizeof(EVP_CIPHER_CTX));
	EVP_CIPHER_CTX_init(ctx);
	
	iv = (unsigned char*)calloc(1, iv_len);
	RAND_bytes(iv, iv_len);
	if (EVP_EncryptInit(ctx, EVP_aes_256_cbc(), shared_secret, iv) == 0) {
		goto fail;
	}
	outbuf = (unsigned char*)calloc(1, plain_len + EVP_CIPHER_block_size(EVP_aes_256_cbc()) + iv_len);
	if (EVP_EncryptUpdate(ctx, outbuf + iv_len, &outlen, plain, plain_len) == 0) {
		goto fail;
	}
	outtot += outlen;
	if (EVP_EncryptFinal(ctx, outbuf + iv_len + outtot, &outlen) == 0) {
		goto fail;
	}
	outtot += outlen;
	
	//We concatenate iv and cipher text together
	memcpy(outbuf, iv, iv_len);
	if (send_msg(sk, outbuf, outtot + iv_len, format) < outtot + iv_len) {
		goto fail;
	}
	
	EVP_CIPHER_CTX_cleanup(ctx);
	free(ctx);
	free(iv);
	free(outbuf);
	return outtot;
	
	
fail:	EVP_CIPHER_CTX_cleanup(ctx);
	free(ctx);
	free(iv);
	if (outbuf != NULL) {
		free(outbuf);
	}
	return -1;
	
}
开发者ID:bbeco,项目名称:secretchat,代码行数:53,代码来源:secretchat_support_lib.c

示例3: AES_CBC_MAC_Create

bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	const EVP_CIPHER * pcipher = NULL;
	EVP_CIPHER_CTX ctx;
	int cbOut;
	byte rgbIV[16] = { 0 };
	byte * rgbOut = NULL;
	bool f = false;
	unsigned int i;
	cn_cbor * cn = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	rgbOut = COSE_CALLOC(16, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	switch (cbKey*8) {
	case 128:
		pcipher = EVP_aes_128_cbc();
		break;

	case 256:
		pcipher = EVP_aes_256_cbc();
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  Setup and run the OpenSSL code

	EVP_CIPHER_CTX_init(&ctx);
	CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);

	for (i = 0; i < (unsigned int)cbAuthData / 16; i++) {
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbAuthData + (i * 16), 16), COSE_ERR_CRYPTO_FAIL);
	}
	if (cbAuthData % 16 != 0) {
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbAuthData + (i * 16), cbAuthData % 16), COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, rgbIV, 16 - (cbAuthData % 16)), COSE_ERR_CRYPTO_FAIL);
	}

	cn = cn_cbor_data_create(rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cn != NULL, COSE_ERR_OUT_OF_MEMORY);
	rgbOut = NULL;

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cn, INDEX_MAC_TAG, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
	cn = NULL;

	EVP_CIPHER_CTX_cleanup(&ctx);
	return !f;

errorReturn:
	if (rgbOut != NULL) COSE_FREE(rgbOut, context);
	if (cn != NULL) CN_CBOR_FREE(cn, context);
	EVP_CIPHER_CTX_cleanup(&ctx);
	return false;
}
开发者ID:KaneRoot,项目名称:COSE-C,代码行数:59,代码来源:openssl.c

示例4: EVP_CIPHER_CTX_init

// Initializes the keys that are going to be used
int Encryption::init() {
	// initialize
	EncryptAesCtx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));

	DecryptAesCtx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));

	// malloc check
	if (EncryptAesCtx == NULL || DecryptAesCtx == NULL) {
		return -1;
	}

    	EVP_CIPHER_CTX_init(EncryptAesCtx);
 
    	EVP_CIPHER_CTX_init(DecryptAesCtx);

	// init AES
	aesKey = (unsigned char*)malloc(AES_KEYLEN/8);
	aesIV = (unsigned char*)malloc(AES_KEYLEN/8);

	unsigned char *aesPass = (unsigned char*)malloc(AES_KEYLEN / 8);
	unsigned char *aesSalt = (unsigned char*)malloc(8);
	
	if(aesKey == NULL || aesIV == NULL || aesPass == NULL || aesSalt == NULL) {
		return -1;
	}

	// Can use password based key derivation for AES, or random data, this uses
	// random data here, can be changed later to fit to project

	#ifdef USE_PBKDF
	
	// Get some random data to use as the AES pass and salt
        if(RAND_bytes(aesPass, AES_KEYLEN/8) == 0) { 
            return -1;
        }

        if(RAND_bytes(aesSalt, 8) == 0) {
            return -1;
        }
     
	// generate 256 bit key
        if(EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), aesSalt, aesPass, AES_KEYLEN/8, AES_ROUNDS, aesKey, aesIV) == 0) {
            return -1;
        }
    #else
        if(RAND_bytes(aesKey, AES_KEYLEN/8) == 0) {
            return -1;
        }

        if(RAND_bytes(aesIV, AES_KEYLEN/8) == 0) {
            return -1;
        }
    #endif

   	free(aesPass);
    	free(aesSalt);
 
    	return 0;
}
开发者ID:aba617,项目名称:CryptChat,代码行数:60,代码来源:Encryption.cpp

示例5: el_aes256_create_key

/**
 * @brief AES256 Create Key function
 * @see el_aes256_encrypt_data()
 * @see el_aes256_decrypt_data()
 * @param key_data The data that will be used to create the key (eg. user+pass)
 * @param key The key generated, based on key_data value
 * @return 0 on success, -1 on error.
 */
int el_aes256_create_key(const unsigned char *key_data, unsigned char *key) {
	int ret, nrounds = 5;
	unsigned char iv[32];

	ret = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key_data, strlen((char *) key_data), nrounds, key, iv);

	return -(ret != 32);
}
开发者ID:ucodev,项目名称:libsidp,代码行数:16,代码来源:aes256cbc.c

示例6: key

void EncryptWrapper::cryptInit(QString pwd){
	QByteArray key(EVP_MAX_KEY_LENGTH,0);
	QByteArray iv(EVP_MAX_IV_LENGTH,0);

//	convert QString to unsigned char
	unsigned char *password = (unsigned char *)malloc(sizeof(unsigned char));
	memcpy(password, pwd.toStdString().c_str(),pwd.size());

	if(!EVP_BytesToKey(EVP_aes_256_cbc(),EVP_sha1(), NULL,
					   (unsigned char *) password,
					   strlen((const char *)password), 1, (unsigned char *)key.data(), (unsigned char *)iv.data())){
		emit errors("EVP_BytesToKey failed: Password "+pwd+" doesn't create.");
		return;
	}
	EVP_CIPHER_CTX_init(&encrypt);
	EVP_EncryptInit(&encrypt, EVP_aes_256_cbc(), (const unsigned char*)key.constData(), (const unsigned char*)iv.constData());
}
开发者ID:bx10,项目名称:cryptfile,代码行数:17,代码来源:encryptwrapper.cpp

示例7: EVP_BytesToKey

	int crypt_ec_helper::encrypt(unsigned char* cipherText, unsigned char *message, int messageLength, unsigned char *secret, int secretLength)
	{
		EVP_CIPHER_CTX *ctx;
		int len, ciphertext_len;
		unsigned char* key = new unsigned char[32];
		unsigned char* iv = new unsigned char[16];

		int keyLen = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(),
			NULL,
			secret, secretLength, 150000,
			key, iv);

		/* Create and initialise the context */
		if (!(ctx = EVP_CIPHER_CTX_new()))
			throw std::runtime_error("Encrypt: Failed to create cipher context.\n");

		/* Initialise the encryption operation. IMPORTANT - ensure you use a key
		* and IV size appropriate for your cipher
		* In this example we are using 256 bit AES (i.e. a 256 bit key). The
		* IV size for *most* modes is the same as the block size. For AES this
		* is 128 bits */
		if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
			throw std::runtime_error("Encrypt: Failed to initialize cipher.\n");

		/* Provide the message to be encrypted, and obtain the encrypted output.
		* EVP_EncryptUpdate can be called multiple times if necessary
		*/
		if (1 != EVP_EncryptUpdate(ctx, cipherText, &len, message, messageLength))
			throw std::runtime_error("Encrypt: Failed to encrypt message.\n");

		ciphertext_len = len;

		/* Finalise the encryption. Further ciphertext bytes may be written at
		* this stage.
		*/
		if (1 != EVP_EncryptFinal_ex(ctx, cipherText + len, &len))
			throw std::runtime_error("Encrypt: Failed to finalize message encryption.\n");

		ciphertext_len += len;

		free(key);
		free(iv);
		EVP_CIPHER_CTX_free(ctx);

		return ciphertext_len;
	}
开发者ID:decentralised-project,项目名称:dc-gui,代码行数:46,代码来源:crypt_ec_helper.cpp

示例8: verify_then_decrypt

/** 
 * @brief Performs basic Encrypt-then-MAC style Authenticated Encryption.
 *
 * @param[in] ekey            a buffer holding the ENC key
 * @param[in] ekey_len        len of ekey buffer
 * @param[in] mkey            a buffer holding the MAC key
 * @param[in] mkey_len        len of mkey buffer
 * @param[in] ctxt            a buffer holding the ciphertext
 * @param[in] ctxt_len        length of ciphertext
 * @param[in] mac             a buffer holding the MAC
 * @param[in] mac_len         length of MAC
 * @param[in] iv              an iv (optional)
 * @param[in] iv_len          length of iv (optional)
 * @param[out] output         an allocated buffer, will hold the plaintext
 * @param[in,out] output_len  length of buffer, will hold length of plaintext
 * @return 0 on success, non-zero on error
 **/
int verify_then_decrypt(const unsigned char *ekey, size_t ekey_len, 
                        const unsigned char *mkey, size_t mkey_len,
                        const unsigned char *ctxt, size_t ctxt_len,
                        const unsigned char *mac, size_t mac_len,
                        const unsigned char *iv, size_t iv_len,
                        unsigned char *output, size_t *output_len)
{
    EVP_CIPHER_CTX *ctx;
    ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER *cipher = NULL;
    unsigned char auth[EVP_MAX_MD_SIZE];
    size_t auth_len = EVP_MAX_MD_SIZE;
    int len;
    
    if (!ekey || !ekey_len || !mkey || !mkey_len || 
        !ctxt || !ctxt_len || !mac || !mac_len || !output || !output_len)
        return -1;
    
    OpenSSL_add_all_algorithms();
    memset(auth, 0, auth_len);

    // Verify the HMAC-SHA1
    if (!HMAC(EVP_sha1(), mkey, mkey_len, ctxt, ctxt_len, 
              auth, (unsigned int *) &auth_len))
        goto cleanup;
    if (auth_len != mac_len) goto cleanup;
    if (memcmp(mac, auth, mac_len) != 0) goto cleanup;

    EVP_CIPHER_CTX_init(ctx);
    switch(ekey_len){
        case 16:
            cipher = (EVP_CIPHER *)EVP_aes_128_cbc();
            break;
        case 24:
            cipher = (EVP_CIPHER *)EVP_aes_192_cbc();
            break;
        case 32:
            cipher = (EVP_CIPHER *)EVP_aes_256_cbc();
            break;
        default:
            return -1;
    }
    if (*output_len < ctxt_len) goto cleanup;
    *output_len = 0;

    if (!EVP_DecryptInit(ctx, cipher, ekey, iv)) goto cleanup;
    if (!EVP_DecryptUpdate(ctx, output, (int *) output_len, 
                           ctxt, ctxt_len)) goto cleanup;
    EVP_DecryptFinal(ctx, output + *output_len, &len);
    *output_len += len;
    
    EVP_CIPHER_CTX_cleanup(ctx);
    return 0;
    
cleanup:
    *output_len = 0;
    return 1;
}
开发者ID:gondree,项目名称:libpdp,代码行数:75,代码来源:pdp_key.c

示例9: get_cipher_type

const EVP_CIPHER* get_cipher_type(const enum cipher cipher, const enum cipher_mode mode) {

    switch (mode) {
        case MODE_ECB:

            switch (cipher) {
                case CIPHER_DES:
                    return EVP_des_ecb();
                case CIPHER_AES_128:
                    return EVP_aes_128_ecb();
                case CIPHER_AES_192:
                    return EVP_aes_192_ecb();
                case CIPHER_AES_256:
                    return EVP_aes_256_ecb();
            }

        case MODE_CBC:

            switch (cipher) {
                case CIPHER_DES:
                    return EVP_des_cbc();
                case CIPHER_AES_128:
                    return EVP_aes_128_cbc();
                case CIPHER_AES_192:
                    return EVP_aes_192_cbc();
                case CIPHER_AES_256:
                    return EVP_aes_256_cbc();
            }

        case MODE_OFB:

            switch (cipher) {
                case CIPHER_DES:
                    return EVP_des_ofb();
                case CIPHER_AES_128:
                    return EVP_aes_128_ofb();
                case CIPHER_AES_192:
                    return EVP_aes_192_ofb();
                case CIPHER_AES_256:
                    return EVP_aes_256_ofb();
            }

        case MODE_CFB:

            switch (cipher) {
                case CIPHER_DES:
                    return EVP_des_cfb();
                case CIPHER_AES_128:
                    return EVP_aes_128_cfb();
                case CIPHER_AES_192:
                    return EVP_aes_192_cfb();
                case CIPHER_AES_256:
                    return EVP_aes_256_cfb();
            }
    }

    abort();
}
开发者ID:acrespo,项目名称:cripto-2013-1c,代码行数:58,代码来源:crypt.c

示例10: encrypt_then_mac

/** 
 * @brief Performs basic Encrypt-then-MAC style Authenticated Encryption.
 *
 * @param[in] ekey          a buffer holding the ENC key
 * @param[in] ekey_len      len of ekey buffer
 * @param[in] mkey          a buffer holding the MAC key
 * @param[in] mkey_len      len of mkey buffer
 * @param[in] input         the plaintext message
 * @param[in] input_len     len of message buffer
 * @param[in,out] ctxt      an allocated buffer, will hold the ciphertext
 * @param[in,out] ctxt_len  length of buffer, will hold length of ciphertext
 * @param[in,out] mac       an allocated buffer, will hold the MAC
 * @param[in,out] mac_len   length of buffer, will hold length of MAC
 * @param[in,out] iv        a randomly chosen iv (optional)
 * @param[in] iv_len        length of buffer for iv (optional)
 * @return 0 on success, non-zero on error
 **/
int encrypt_then_mac(const unsigned char *ekey, size_t ekey_len, 
                     const unsigned char *mkey, size_t mkey_len,
                     const unsigned char *input, size_t input_len,
                     unsigned char *ctxt, size_t *ctxt_len,
                     unsigned char *mac, size_t *mac_len,
                     unsigned char *iv, size_t iv_len)
{
    EVP_CIPHER_CTX *ctx;
    ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER *cipher = NULL;
    int len;
    
    if (!ekey || !ekey_len || !mkey || !mkey_len || 
        !input_len || !ctxt || !ctxt_len || !mac || !mac_len)
        return -1;
    
    OpenSSL_add_all_algorithms();
    
    EVP_CIPHER_CTX_init(ctx);
    switch(ekey_len){
        case 16:
            cipher = (EVP_CIPHER *)EVP_aes_128_cbc();
            break;
        case 24:
            cipher = (EVP_CIPHER *)EVP_aes_192_cbc();
            break;
        case 32:
            cipher = (EVP_CIPHER *)EVP_aes_256_cbc();
            break;
        default:
            return -1;
    }

    if (iv && iv_len) {
        if (!RAND_bytes(iv, iv_len)) goto cleanup;
    }

    if (!EVP_EncryptInit(ctx, cipher, ekey, iv)) goto cleanup;    

    *ctxt_len = 0;
    if (!EVP_EncryptUpdate(ctx, ctxt, (int *) ctxt_len, input, input_len))
        goto cleanup;
    EVP_EncryptFinal(ctx, ctxt + *ctxt_len, &len);
    *ctxt_len += len;
    
    // Do the HMAC-SHA1
    *mac_len = 0;
    if (!HMAC(EVP_sha1(), mkey, mkey_len, ctxt, *ctxt_len,
                          mac, (unsigned int *) mac_len))
        goto cleanup;
    EVP_CIPHER_CTX_cleanup(ctx);
    return 0;
    
cleanup:
    if (ctxt_len) *ctxt_len = 0;
    if (mac_len) *mac_len = 0;
    return 1;
}
开发者ID:gondree,项目名称:libpdp,代码行数:75,代码来源:pdp_key.c

示例11: openssl_encrypt

int openssl_encrypt(struct emvpn_socket *v, uint8_t *to, uint8_t *from, int len)
{
    int clen, flen = 0;
    EVP_CIPHER_CTX_init(&enc);
    EVP_EncryptInit(&enc, EVP_aes_256_cbc(), v->key.key, v->key.iv);
    EVP_EncryptUpdate(&enc, to, &clen, from, len);
    EVP_EncryptFinal_ex(&enc, to + clen, &flen);
    return clen + (flen % 16) ;
}
开发者ID:Zengwn,项目名称:emvpn,代码行数:9,代码来源:crypto_openssl.c

示例12: aes_init

int aes_init(unsigned char* pwd, unsigned int pwd_len, unsigned char * salt, EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx)
{
	int i, rounds =5; 					/* rounds */
	unsigned char key[32], iv[32];
	
	i = EVP_BytesToKey(EVP_aes_256_cbc(),EVP_sha1(),salt,pwd,pwd_len,rounds,key,iv);
	if(i != 32)
	{
		printf("\n Error,Incorrect key size generated:%d:\n",i);
		return -1;
	}
	
	EVP_CIPHER_CTX_init(e_ctx);
	EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
	EVP_CIPHER_CTX_init(d_ctx);
        EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
	return 0;
}
开发者ID:stevezhougs,项目名称:mpro,代码行数:18,代码来源:aes2.c

示例13: el_chacha_avx_create_key

/**
 * @brief ChaCha-AVX Create Key function
 * @see el_chacha_avx_encrypt_data()
 * @see el_chacha_avx_decrypt_data()
 * @param key_data The data that will be used to create the key (eg. user+pass)
 * @param key The key generated, based on key_data value
 * @return 0 on success, -1 on error.
 */
int el_chacha_avx_create_key(const unsigned char *key_data, unsigned char *key) {
	int ret, nrounds = 5;
	unsigned char iv[32];

	/* XXX: Get rid of openssl from chacha_avx code asap */
	ret = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key_data, strlen((char *) key_data), nrounds, key, iv);

	return -(ret != 32);
}
开发者ID:ucodev,项目名称:libsidp,代码行数:17,代码来源:chacha-avx.c

示例14: s2n_cbc_cipher_aes256_set_encryption_key

int s2n_cbc_cipher_aes256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
{
    eq_check(in->size, 256 / 8);

    EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
    GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);

    return 0;
}
开发者ID:gibson-compsci,项目名称:s2n,代码行数:9,代码来源:s2n_cbc_cipher_aes.c

示例15: EVP_aes_128_cbc

/*
 * return OpenSSL cipher for JWE encryption algorithm
 */
static const EVP_CIPHER *apr_jwe_enc_to_openssl_cipher(const char *enc) {
	if (apr_strnatcmp(enc, "A128CBC-HS256") == 0) {
		return EVP_aes_128_cbc();
	}
	if (apr_strnatcmp(enc, "A256CBC-HS512") == 0) {
		return EVP_aes_256_cbc();
	}
	return NULL;
}
开发者ID:jisqyv,项目名称:mod_auth_openidc,代码行数:12,代码来源:apr_jwe.c


注:本文中的EVP_aes_256_cbc函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。