本文整理汇总了C++中crypto_rand函数的典型用法代码示例。如果您正苦于以下问题:C++ crypto_rand函数的具体用法?C++ crypto_rand怎么用?C++ crypto_rand使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了crypto_rand函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: bench_cell_ops
static void
bench_cell_ops(void)
{
const int iters = 1<<16;
int i;
/* benchmarks for cell ops at relay. */
or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
cell_t *cell = tor_malloc(sizeof(cell_t));
int outbound;
uint64_t start, end;
crypto_rand((char*)cell->payload, sizeof(cell->payload));
/* Mock-up or_circuit_t */
or_circ->base_.magic = OR_CIRCUIT_MAGIC;
or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;
/* Initialize crypto */
char key1[CIPHER_KEY_LEN], key2[CIPHER_KEY_LEN];
crypto_rand(key1, sizeof(key1));
crypto_rand(key2, sizeof(key2));
or_circ->p_crypto = crypto_cipher_new(key1);
or_circ->n_crypto = crypto_cipher_new(key2);
or_circ->p_digest = crypto_digest_new();
or_circ->n_digest = crypto_digest_new();
reset_perftime();
for (outbound = 0; outbound <= 1; ++outbound) {
cell_direction_t d = outbound ? CELL_DIRECTION_OUT : CELL_DIRECTION_IN;
start = perftime();
for (i = 0; i < iters; ++i) {
char recognized = 0;
crypt_path_t *layer_hint = NULL;
relay_crypt(TO_CIRCUIT(or_circ), cell, d, &layer_hint, &recognized);
}
end = perftime();
printf("%sbound cells: %.2f ns per cell. (%.2f ns per byte of payload)\n",
outbound?"Out":" In",
NANOCOUNT(start,end,iters),
NANOCOUNT(start,end,iters*CELL_PAYLOAD_SIZE));
}
crypto_digest_free(or_circ->p_digest);
crypto_digest_free(or_circ->n_digest);
crypto_cipher_free(or_circ->p_crypto);
crypto_cipher_free(or_circ->n_crypto);
tor_free(or_circ);
tor_free(cell);
}
开发者ID:francois-wellenreiter,项目名称:tor,代码行数:51,代码来源:bench.c
示例2: test_crypto_rng
/** Run unit tests for our random number generation function and its wrappers.
*/
static void
test_crypto_rng(void *arg)
{
int i, j, allok;
char data1[100], data2[100];
double d;
char *h=NULL;
/* Try out RNG. */
(void)arg;
tt_assert(! crypto_seed_rng());
crypto_rand(data1, 100);
crypto_rand(data2, 100);
tt_mem_op(data1,OP_NE, data2,100);
allok = 1;
for (i = 0; i < 100; ++i) {
uint64_t big;
char *host;
j = crypto_rand_int(100);
if (j < 0 || j >= 100)
allok = 0;
big = crypto_rand_uint64(UINT64_C(1)<<40);
if (big >= (UINT64_C(1)<<40))
allok = 0;
big = crypto_rand_uint64(UINT64_C(5));
if (big >= 5)
allok = 0;
d = crypto_rand_double();
tt_assert(d >= 0);
tt_assert(d < 1.0);
host = crypto_random_hostname(3,8,"www.",".onion");
if (strcmpstart(host,"www.") ||
strcmpend(host,".onion") ||
strlen(host) < 13 ||
strlen(host) > 18)
allok = 0;
tor_free(host);
}
/* Make sure crypto_random_hostname clips its inputs properly. */
h = crypto_random_hostname(20000, 9000, "www.", ".onion");
tt_assert(! strcmpstart(h,"www."));
tt_assert(! strcmpend(h,".onion"));
tt_int_op(63+4+6, OP_EQ, strlen(h));
tt_assert(allok);
done:
tor_free(h);
}
开发者ID:jfrazelle,项目名称:tor,代码行数:51,代码来源:test_crypto_rng.c
示例3: fast_server_handshake
/** Implement the server side of the CREATE_FAST abbreviated handshake. The
* client has provided DIGEST_LEN key bytes in <b>key_in</b> ("x"). We
* generate a reply of DIGEST_LEN*2 bytes in <b>key_out</b>, consisting of a
* new random "y", followed by H(x|y) to check for correctness. We set
* <b>key_out_len</b> bytes of key material in <b>key_out</b>.
* Return 0 on success, <0 on failure.
**/
int
fast_server_handshake(const uint8_t *key_in, /* DIGEST_LEN bytes */
uint8_t *handshake_reply_out, /* DIGEST_LEN*2 bytes */
uint8_t *key_out,
size_t key_out_len)
{
uint8_t tmp[DIGEST_LEN+DIGEST_LEN];
uint8_t *out = NULL;
size_t out_len;
int r = -1;
crypto_rand((char*)handshake_reply_out, DIGEST_LEN);
memcpy(tmp, key_in, DIGEST_LEN);
memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
out_len = key_out_len+DIGEST_LEN;
out = tor_malloc(out_len);
if (BUG(crypto_expand_key_material_TAP(tmp, sizeof(tmp), out, out_len))) {
goto done; // LCOV_EXCL_LINE
}
memcpy(handshake_reply_out+DIGEST_LEN, out, DIGEST_LEN);
memcpy(key_out, out+DIGEST_LEN, key_out_len);
r = 0;
done:
memwipe(tmp, 0, sizeof(tmp));
memwipe(out, 0, out_len);
tor_free(out);
return r;
}
开发者ID:Samdney,项目名称:tor,代码行数:36,代码来源:onion_fast.c
示例4: helper_establish_intro_v2
/* Helper function: Send a well-formed v2 ESTABLISH_INTRO cell to
* <b>intro_circ</b>. Return the public key advertised in the cell. */
static crypto_pk_t *
helper_establish_intro_v2(or_circuit_t *intro_circ)
{
crypto_pk_t *key1 = NULL;
int retval;
uint8_t cell_body[RELAY_PAYLOAD_SIZE];
ssize_t cell_len = 0;
char circ_nonce[DIGEST_LEN] = {0};
tt_assert(intro_circ);
/* Prepare the circuit for the incoming ESTABLISH_INTRO */
crypto_rand(circ_nonce, sizeof(circ_nonce));
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Send legacy establish_intro */
key1 = pk_generate(0);
/* Use old circ_nonce why not */
cell_len = rend_service_encode_establish_intro_cell(
(char*)cell_body,
sizeof(cell_body), key1,
circ_nonce);
tt_int_op(cell_len, OP_GT, 0);
/* Receive legacy establish_intro */
retval = hs_intro_received_establish_intro(intro_circ,
cell_body, (size_t) cell_len);
tt_int_op(retval, OP_EQ, 0);
done:
return key1;
}
开发者ID:torproject,项目名称:tor,代码行数:35,代码来源:test_hs_intropoint.c
示例5: helper_establish_intro_v3
/* Helper function: Send a well-formed v3 ESTABLISH_INTRO cell to
* <b>intro_circ</b>. Return the cell. */
static trn_cell_establish_intro_t *
helper_establish_intro_v3(or_circuit_t *intro_circ)
{
int retval;
char circ_nonce[DIGEST_LEN] = {0};
uint8_t cell_body[RELAY_PAYLOAD_SIZE];
ssize_t cell_len = 0;
trn_cell_establish_intro_t *cell = NULL;
tt_assert(intro_circ);
/* Prepare the circuit for the incoming ESTABLISH_INTRO */
crypto_rand(circ_nonce, sizeof(circ_nonce));
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
* attempt to parse it. */
cell_len = new_establish_intro_cell(circ_nonce, &cell);
tt_i64_op(cell_len, OP_GT, 0);
tt_assert(cell);
cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
cell);
tt_int_op(cell_len, OP_GT, 0);
/* Receive the cell */
retval = hs_intro_received_establish_intro(intro_circ, cell_body,
(size_t) cell_len);
tt_int_op(retval, OP_EQ, 0);
done:
return cell;
}
开发者ID:torproject,项目名称:tor,代码行数:34,代码来源:test_hs_intropoint.c
示例6: test_establish_intro_wrong_sig
/* Send a legit ESTABLISH_INTRO cell but slightly change the signature. Should
* fail. */
static void
test_establish_intro_wrong_sig(void *arg)
{
int retval;
char circ_nonce[DIGEST_LEN] = {0};
uint8_t cell_body[RELAY_PAYLOAD_SIZE];
ssize_t cell_len = 0;
or_circuit_t *intro_circ = or_circuit_new(0,NULL);
(void) arg;
/* Get the auth key of the intro point */
crypto_rand(circ_nonce, sizeof(circ_nonce));
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
attempt to parse it. */
cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
tt_i64_op(cell_len, OP_GT, 0);
/* Mutate the last byte (signature)! :) */
cell_body[cell_len - 1]++;
/* Receive the cell. Should fail. */
setup_full_capture_of_logs(LOG_INFO);
retval = hs_intro_received_establish_intro(intro_circ, cell_body,
(size_t)cell_len);
expect_log_msg_containing("Failed to verify ESTABLISH_INTRO cell.");
teardown_capture_of_logs();
tt_int_op(retval, OP_EQ, -1);
done:
circuit_free_(TO_CIRCUIT(intro_circ));
}
开发者ID:torproject,项目名称:tor,代码行数:36,代码来源:test_hs_intropoint.c
示例7: test_establish_intro_wrong_purpose
/* Try sending an ESTABLISH_INTRO cell on a circuit that is already an intro
* point. Should fail. */
static void
test_establish_intro_wrong_purpose(void *arg)
{
int retval;
ssize_t cell_len = 0;
char circ_nonce[DIGEST_LEN] = {0};
uint8_t cell_body[RELAY_PAYLOAD_SIZE];
or_circuit_t *intro_circ = or_circuit_new(0,NULL);
(void)arg;
/* Get the auth key of the intro point */
crypto_rand(circ_nonce, sizeof(circ_nonce));
memcpy(intro_circ->rend_circ_nonce, circ_nonce, DIGEST_LEN);
/* Set a bad circuit purpose!! :) */
circuit_change_purpose(TO_CIRCUIT(intro_circ), CIRCUIT_PURPOSE_INTRO_POINT);
/* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
attempt to parse it. */
cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
tt_i64_op(cell_len, OP_GT, 0);
/* Receive the cell. Should fail. */
setup_full_capture_of_logs(LOG_INFO);
retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
expect_log_msg_containing("Rejecting ESTABLISH_INTRO on non-OR circuit.");
teardown_capture_of_logs();
tt_int_op(retval, OP_EQ, -1);
done:
circuit_free_(TO_CIRCUIT(intro_circ));
}
开发者ID:torproject,项目名称:tor,代码行数:35,代码来源:test_hs_intropoint.c
示例8: bench_cell_aes
static void
bench_cell_aes(void)
{
uint64_t start, end;
const int len = 509;
const int iters = (1<<16);
const int max_misalign = 15;
char *b = tor_malloc(len+max_misalign);
crypto_cipher_t *c;
int i, misalign;
char key[CIPHER_KEY_LEN];
crypto_rand(key, sizeof(key));
c = crypto_cipher_new(key);
reset_perftime();
for (misalign = 0; misalign <= max_misalign; ++misalign) {
start = perftime();
for (i = 0; i < iters; ++i) {
crypto_cipher_crypt_inplace(c, b+misalign, len);
}
end = perftime();
printf("%d bytes, misaligned by %d: %.2f nsec per byte\n", len, misalign,
NANOCOUNT(start, end, iters*len));
}
crypto_cipher_free(c);
tor_free(b);
}
开发者ID:francois-wellenreiter,项目名称:tor,代码行数:28,代码来源:bench.c
示例9: test_gen_establish_intro_cell_bad
/** We simulate a failure to create an ESTABLISH_INTRO cell */
static void
test_gen_establish_intro_cell_bad(void *arg)
{
(void) arg;
ssize_t cell_len = 0;
trn_cell_establish_intro_t *cell = NULL;
char circ_nonce[DIGEST_LEN] = {0};
hs_service_intro_point_t *ip = NULL;
MOCK(ed25519_sign_prefixed, mock_ed25519_sign_prefixed);
crypto_rand(circ_nonce, sizeof(circ_nonce));
setup_full_capture_of_logs(LOG_WARN);
/* Easiest way to make that function fail is to mock the
ed25519_sign_prefixed() function and make it fail. */
cell = trn_cell_establish_intro_new();
tt_assert(cell);
ip = service_intro_point_new(NULL);
cell_len = hs_cell_build_establish_intro(circ_nonce, ip, NULL);
service_intro_point_free(ip);
expect_log_msg_containing("Unable to make signature for "
"ESTABLISH_INTRO cell.");
teardown_capture_of_logs();
tt_i64_op(cell_len, OP_EQ, -1);
done:
trn_cell_establish_intro_free(cell);
UNMOCK(ed25519_sign_prefixed);
}
开发者ID:torproject,项目名称:tor,代码行数:31,代码来源:test_hs_cell.c
示例10: fast_server_handshake
/** Implement the server side of the CREATE_FAST abbreviated handshake. The
* client has provided DIGEST_LEN key bytes in <b>key_in</b> ("x"). We
* generate a reply of DIGEST_LEN*2 bytes in <b>key_out</b>, consisting of a
* new random "y", followed by H(x|y) to check for correctness. We set
* <b>key_out_len</b> bytes of key material in <b>key_out</b>.
* Return 0 on success, <0 on failure.
**/
int
fast_server_handshake(const char *key_in, /* DIGEST_LEN bytes */
char *handshake_reply_out, /* DIGEST_LEN*2 bytes */
char *key_out,
size_t key_out_len)
{
char tmp[DIGEST_LEN+DIGEST_LEN];
char *out = NULL;
size_t out_len;
int r = -1;
if (crypto_rand(handshake_reply_out, DIGEST_LEN)<0)
return -1;
memcpy(tmp, key_in, DIGEST_LEN);
memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
out_len = key_out_len+DIGEST_LEN;
out = tor_malloc(out_len);
if (crypto_expand_key_material(tmp, sizeof(tmp), out, out_len)) {
goto done;
}
memcpy(handshake_reply_out+DIGEST_LEN, out, DIGEST_LEN);
memcpy(key_out, out+DIGEST_LEN, key_out_len);
r = 0;
done:
memset(tmp, 0, sizeof(tmp));
memset(out, 0, out_len);
tor_free(out);
return r;
}
开发者ID:kitsune-dsu,项目名称:kitsune-tor,代码行数:37,代码来源:onion.c
示例11: test_crypto_base32_decode
/** Test base32 decoding. */
static void
test_crypto_base32_decode(void)
{
char plain[60], encoded[96 + 1], decoded[60];
int res;
crypto_rand(plain, 60);
/* Encode and decode a random string. */
base32_encode(encoded, 96 + 1, plain, 60);
res = base32_decode(decoded, 60, encoded, 96);
test_eq(res, 0);
test_memeq(plain, decoded, 60);
/* Encode, uppercase, and decode a random string. */
base32_encode(encoded, 96 + 1, plain, 60);
tor_strupper(encoded);
res = base32_decode(decoded, 60, encoded, 96);
test_eq(res, 0);
test_memeq(plain, decoded, 60);
/* Change encoded string and decode. */
if (encoded[0] == 'A' || encoded[0] == 'a')
encoded[0] = 'B';
else
encoded[0] = 'A';
res = base32_decode(decoded, 60, encoded, 96);
test_eq(res, 0);
test_memneq(plain, decoded, 60);
/* Bad encodings. */
encoded[0] = '!';
res = base32_decode(decoded, 60, encoded, 96);
test_assert(res < 0);
done:
;
}
开发者ID:Lab414,项目名称:30May,代码行数:34,代码来源:test_crypto.c
示例12: rend_client_send_establish_rendezvous
/** Send the establish-rendezvous cell along a rendezvous circuit. if
* it fails, mark the circ for close and return -1. else return 0.
*/
static int
rend_client_send_establish_rendezvous(origin_circuit_t *circ)
{
tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
tor_assert(circ->rend_data);
log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");
crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN);
/* Set timestamp_dirty, because circuit_expire_building expects it,
* and the rend cookie also means we've used the circ. */
circ->base_.timestamp_dirty = time(NULL);
/* We've attempted to use this circuit. Probe it if we fail */
pathbias_count_use_attempt(circ);
if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
circ->rend_data->rend_cookie,
REND_COOKIE_LEN,
circ->cpath->prev)<0) {
/* circ is already marked for close */
log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell");
return -1;
}
return 0;
}
开发者ID:Samdney,项目名称:tor,代码行数:31,代码来源:rendclient.c
示例13: test_routerlist_launch_descriptor_downloads
static void
test_routerlist_launch_descriptor_downloads(void *arg)
{
smartlist_t *downloadable = smartlist_new();
time_t now = time(NULL);
char *cp;
(void)arg;
for (int i = 0; i < 100; i++) {
cp = tor_malloc(DIGEST256_LEN);
tt_assert(cp);
crypto_rand(cp, DIGEST256_LEN);
smartlist_add(downloadable, cp);
}
MOCK(initiate_descriptor_downloads, mock_initiate_descriptor_downloads);
launch_descriptor_downloads(DIR_PURPOSE_FETCH_MICRODESC, downloadable,
NULL, now);
tt_int_op(3, ==, count);
UNMOCK(initiate_descriptor_downloads);
done:
SMARTLIST_FOREACH(downloadable, char *, cp1, tor_free(cp1));
smartlist_free(downloadable);
}
开发者ID:BwRy,项目名称:Astoria,代码行数:25,代码来源:test_routerlist.c
示例14: test_buffers_tls_read_mocked
static void
test_buffers_tls_read_mocked(void *arg)
{
uint8_t *mem;
buf_t *buf;
(void)arg;
mem = tor_malloc(64*1024);
crypto_rand((char*)mem, 64*1024);
tls_read_ptr = mem;
n_remaining = 64*1024;
MOCK(tor_tls_read, mock_tls_read);
buf = buf_new();
next_reply_val[0] = 1024;
tt_int_op(128, ==, read_to_buf_tls(NULL, 128, buf));
next_reply_val[0] = 5000;
next_reply_val[1] = 5000;
tt_int_op(6000, ==, read_to_buf_tls(NULL, 6000, buf));
done:
UNMOCK(tor_tls_read);
tor_free(mem);
buf_free(buf);
}
开发者ID:HansoHan,项目名称:tor-1,代码行数:28,代码来源:test_buffers.c
示例15: bench_aes
/** Run AES performance benchmarks. */
static void
bench_aes(void)
{
int len, i;
char *b1, *b2;
crypto_cipher_t *c;
uint64_t start, end;
const int bytes_per_iter = (1<<24);
reset_perftime();
char key[CIPHER_KEY_LEN];
crypto_rand(key, sizeof(key));
c = crypto_cipher_new(key);
for (len = 1; len <= 8192; len *= 2) {
int iters = bytes_per_iter / len;
b1 = tor_malloc_zero(len);
b2 = tor_malloc_zero(len);
start = perftime();
for (i = 0; i < iters; ++i) {
crypto_cipher_encrypt(c, b1, b2, len);
}
end = perftime();
tor_free(b1);
tor_free(b2);
printf("%d bytes: %.2f nsec per byte\n", len,
NANOCOUNT(start, end, iters*len));
}
crypto_cipher_free(c);
}
开发者ID:francois-wellenreiter,项目名称:tor,代码行数:30,代码来源:bench.c
示例16: rend_client_send_establish_rendezvous
/** Send the establish-rendezvous cell along a rendezvous circuit. if
* it fails, mark the circ for close and return -1. else return 0.
*/
static int
rend_client_send_establish_rendezvous(origin_circuit_t *circ)
{
tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
tor_assert(circ->rend_data);
log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");
if (crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN) < 0) {
log_warn(LD_BUG, "Internal error: Couldn't produce random cookie.");
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
return -1;
}
/* Set timestamp_dirty, because circuit_expire_building expects it,
* and the rend cookie also means we've used the circ. */
circ->base_.timestamp_dirty = time(NULL);
if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
circ->rend_data->rend_cookie,
REND_COOKIE_LEN,
circ->cpath->prev)<0) {
/* circ is already marked for close */
log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell");
return -1;
}
return 0;
}
开发者ID:grubWare,项目名称:hibernate,代码行数:32,代码来源:rendclient.c
示例17: get_fname_rnd
/** Return a filename with a random suffix, relative to our testing temporary
* directory. If name is NULL, return the name of the testing temporary
* directory, without any suffix. */
const char *
get_fname_rnd(const char *name)
{
char rnd[256], rnd32[256];
crypto_rand(rnd, RAND_PATH_BYTES);
base32_encode(rnd32, sizeof(rnd32), rnd, RAND_PATH_BYTES);
return get_fname_suffix(name, rnd32);
}
开发者ID:Samdney,项目名称:tor,代码行数:11,代码来源:testing_common.c
示例18: randombytes
int
randombytes(char *out, size_t num_bytes)
{
if (crypto_rand(out, num_bytes) < 0)
{
DRBG_RET(DRBG_ENTROPY_FAIL);
}
DRBG_RET(DRBG_OK);
}
开发者ID:zhenfeizhang,项目名称:ntru-tor-local,代码行数:9,代码来源:crypto_ntruees439ep1.c
示例19: cell_ewma_initialize_ticks
/**
* Initialize the system that tells which ewma tick we are in.
*/
STATIC void
cell_ewma_initialize_ticks(void)
{
if (ewma_ticks_initialized)
return;
monotime_coarse_get(&start_of_current_tick);
crypto_rand((char*)¤t_tick_num, sizeof(current_tick_num));
ewma_ticks_initialized = 1;
}
开发者ID:jfrazelle,项目名称:tor,代码行数:12,代码来源:circuitmux_ewma.c
示例20: curve25519_rand_seckey_bytes
/**
* Generate CURVE25519_SECKEY_LEN random bytes in <b>out</b>. If
* <b>extra_strong</b> is true, this key is possibly going to get used more
* than once, so use a better-than-usual RNG. Return 0 on success, -1 on
* failure.
*
* This function does not adjust the output of the RNG at all; the will caller
* will need to clear or set the appropriate bits to make curve25519 work.
*/
int
curve25519_rand_seckey_bytes(uint8_t *out, int extra_strong)
{
if (extra_strong)
crypto_strongest_rand(out, CURVE25519_SECKEY_LEN);
else
crypto_rand((char*)out, CURVE25519_SECKEY_LEN);
return 0;
}
开发者ID:1234max,项目名称:tor,代码行数:19,代码来源:crypto_curve25519.c
注:本文中的crypto_rand函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论