3 Star 12 Fork 3

纵使有花兼明月何堪无酒亦无人 / xukey

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ukey.c 12.74 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Liexusong <liexusong@qq.com>
| Author: Liexusong <499873958@qq.com> 添加随机字符串 随机数字功能
+----------------------------------------------------------------------+
*/
/* $Id: header 297205 2010-03-30 21:09:07Z johannes $ */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "main/SAPI.h"
#include "php_ukey.h"
#include "spinlock.h"
#include "shm.h"
int ncpu;
/* True global resources - no need for thread safety here */
static int pid = -1;
static int module_init = 0;
static int le_ukey;
static int datacenter_id;
static int worker_id = -1;
static __uint64_t twepoch;
static char *memaddr;
static struct shm shmctx;
static ukey_context_t *context;
static atomic_t *lock;
/* {{{ ukey_functions[]
*
* Every user visible function must have an entry in ukey_functions[].
*/
const zend_function_entry ukey_functions[] = {
PHP_FE(ukey_next_id, NULL)
PHP_FE(ukey_to_timestamp, NULL)
PHP_FE(ukey_to_machine, NULL)
PHP_FE(get_random_str, NULL)/* For testing, remove later. */
PHP_FE(get_random__num_str, NULL)/* For testing, remove later. */
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ ukey_module_entry
*/
zend_module_entry ukey_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"ukey",
ukey_functions,
PHP_MINIT(ukey),
PHP_MSHUTDOWN(ukey),
PHP_RINIT(ukey),
PHP_RSHUTDOWN(ukey),
PHP_MINFO(ukey),
#if ZEND_MODULE_API_NO >= 20010901
"0.3", /* Replace with version number for your extension */
#endif
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_UKEY
ZEND_GET_MODULE(ukey)
#endif
ZEND_INI_MH(ukey_ini_datacenter_id)
{
if (new_value_length == 0) {
return FAILURE;
}
datacenter_id = atoi(new_value);
if (datacenter_id < 0) {
return FAILURE;
}
return SUCCESS;
}
ZEND_INI_MH(ukey_ini_twepoch)
{
if (new_value_length == 0) {
return FAILURE;
}
sscanf(new_value, "%llu", &twepoch);
if (twepoch <= 0ULL) {
return FAILURE;
}
return SUCCESS;
}
PHP_INI_BEGIN()
PHP_INI_ENTRY("ukey.datacenter", "0", PHP_INI_ALL,
ukey_ini_datacenter_id)
PHP_INI_ENTRY("ukey.twepoch", "1288834974657", PHP_INI_ALL,
ukey_ini_twepoch)
PHP_INI_END()
int
ukey_startup(__uint64_t twepoch, int datacenter_id)
{
/* If is CLI's SAPI,
* we don't use share memory. */
if (!strcasecmp(sapi_module.name, "cli")) {
memaddr = malloc(sizeof(atomic_t) + sizeof(ukey_context_t));
if (!memaddr) {
php_printf("Fatal error: Not enough memory.\n");
return -1;
}
lock = memaddr;
context = memaddr + sizeof(atomic_t);
} else {
shmctx.size = sizeof(atomic_t) + sizeof(ukey_context_t);
if (shm_alloc(&shmctx) == -1) {
php_printf("Fatal error: Not enough memory.\n");
return -1;
}
lock = shmctx.addr;
context = (char *)shmctx.addr + sizeof(atomic_t);
}
*lock = 0; /* set lock to zero */
context->twepoch = twepoch;
context->datacenter_id = datacenter_id;
context->sequence = 0;
context->last_timestamp = 0ULL;
context->worker_id_bits = 5;
context->datacenter_id_bits = 5;
context->sequence_bits = 12;
context->worker_id_shift = context->sequence_bits;
context->datacenter_id_shift = context->sequence_bits +
context->worker_id_bits;
context->timestamp_left_shift = context->sequence_bits +
context->worker_id_bits + context->datacenter_id_bits;
context->sequence_mask = -1 ^ (-1 << context->sequence_bits);
return 0;
}
void
ukey_shutdown()
{
if (!module_init) {
return;
}
if (!strcasecmp(sapi_module.name, "cli")) {
free(memaddr);
} else {
shm_free(&shmctx);
}
module_init = 0;
}
static void
exit_cb(void)
{
if (lock == pid) {
spin_unlock(lock, pid);
}
ukey_shutdown();
}
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(ukey)
{
REGISTER_INI_ENTRIES();
if (ukey_startup(twepoch, datacenter_id) == -1) {
return FAILURE;
}
ncpu = sysconf(_SC_NPROCESSORS_ONLN);
if (ncpu <= 0) {
ncpu = 1;
}
atexit(exit_cb);
module_init = 1;
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(ukey)
{
UNREGISTER_INI_ENTRIES();
ukey_shutdown();
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(ukey)
{
if (pid == -1) { /* init process ID */
pid = (int)getpid();
}
if (worker_id == -1) { /* init worker ID */
worker_id = pid & 0x1F;
}
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(ukey)
{
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(ukey)
{
php_info_print_table_start();
php_info_print_table_header(2, "ukey support", "enabled");
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
/* }}} */
static __uint64_t
realtime()
{
struct timeval tv;
__uint64_t retval;
if (gettimeofday(&tv, NULL) == -1) {
return 0ULL;
}
retval = (__uint64_t)tv.tv_sec * 1000ULL +
(__uint64_t)tv.tv_usec / 1000ULL;
return retval;
}
static __uint64_t
skip_next_millis()
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000; /* 1 millisecond */
select(0, NULL, NULL, NULL, &tv); /* waiting */
return realtime();
}
/* Every user-visible function in PHP should document itself in the source */
/* {{{ proto string ukey_next_id(void) */
PHP_FUNCTION(ukey_next_id)
{
__uint64_t timestamp = realtime();
__uint64_t retval;
int len;
char buf[128];
if (timestamp == 0ULL) {
RETURN_FALSE;
}
spin_lock(lock, pid);
if (context->last_timestamp == timestamp) {
context->sequence = (context->sequence + 1) & context->sequence_mask;
if (context->sequence == 0) {
timestamp = skip_next_millis();
}
} else {
context->sequence = 0; /* Back to zero */
}
context->last_timestamp = timestamp;
retval = ((timestamp - context->twepoch) << context->timestamp_left_shift)
| (context->datacenter_id << context->datacenter_id_shift)
| (worker_id << context->worker_id_shift)
| context->sequence;
spin_unlock(lock, pid);
len = sprintf(buf, "%llu", retval);
RETURN_STRINGL(buf, len, 1);
}
/* }}} */
static __uint64_t
ukey_change_uint64(char *key)
{
__uint64_t retval;
if (sscanf(key, "%llu", &retval) == 0) {
return 0;
}
return retval;
}
/* {{{ proto int ukey_to_timestamp(string key) */
PHP_FUNCTION(ukey_to_timestamp)
{
__uint64_t id;
char *key;
int len, ts;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key,
&len TSRMLS_CC) == FAILURE)
{
RETURN_FALSE;
}
id = ukey_change_uint64(key);
if (!id) {
RETURN_FALSE;
}
/* Don't need lock share here,
* Because timestamp_left_shift and twepoch unchanging */
id = (id >> context->timestamp_left_shift) + context->twepoch;
ts = id / 1000ULL;
RETURN_LONG(ts);
}
/* }}} */
/* {{{ proto array ukey_to_machine(string key) */
PHP_FUNCTION(ukey_to_machine)
{
__uint64_t id;
int datacenter, worker;
char *key;
int len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key,
&len TSRMLS_CC) == FAILURE)
{
RETURN_FALSE;
}
id = ukey_change_uint64(key);
if (!id) {
RETURN_FALSE;
}
/* Don't need lock share here,
* Because datacenter_id_shift and worker_id_shift unchanging */
datacenter = (id >> context->datacenter_id_shift) & 0x1FULL;
worker = (id >> context->worker_id_shift) & 0x1FULL;
array_init(return_value);
add_assoc_long(return_value, "datacenter", datacenter);
add_assoc_long(return_value, "worker", worker);
return;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
PHP_FUNCTION(get_random_str)
{
int length=8;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE)
{
length=8;
}
length++;
int flag, i;
char string[length];
__uint64_t timestamp = realtime();
__uint64_t retval;
int len;
char buf[128];
if (timestamp == 0ULL) {
RETURN_FALSE;
}
spin_lock(lock, pid);
if (context->last_timestamp == timestamp) {
context->sequence = (context->sequence + 1) & context->sequence_mask;
if (context->sequence == 0) {
timestamp = skip_next_millis();
}
} else {
context->sequence = 0; /* Back to zero */
}
context->last_timestamp = timestamp;
retval = ((timestamp - context->twepoch) << context->timestamp_left_shift)
| (context->datacenter_id << context->datacenter_id_shift)
| (worker_id << context->worker_id_shift)
| context->sequence;
spin_unlock(lock, pid);
//printf('%ld',retval);
srand((unsigned)retval);
//srand((unsigned) time(NULL ));
for (i = 0; i < length - 1; i++)
{
flag = rand() % 3;
switch (flag)
{
case 0:
string[i] = 'A' + rand() % 26;
break;
case 1:
string[i] = 'a' + rand() % 26;
break;
case 2:
string[i] = '0' + rand() % 10;
break;
default:
string[i] = 'x';
break;
}
}
string[length - 1] = '\0';
RETURN_STRINGL(string,length,0);
}
PHP_FUNCTION(get_random__num_str)
{
int length=8;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE)
{
length=8;
}
length++;
int flag, i;
char string[length];
__uint64_t timestamp = realtime();
__uint64_t retval;
int len;
char buf[128];
if (timestamp == 0ULL) {
RETURN_FALSE;
}
spin_lock(lock, pid);
if (context->last_timestamp == timestamp) {
context->sequence = (context->sequence + 1) & context->sequence_mask;
if (context->sequence == 0) {
timestamp = skip_next_millis();
}
} else {
context->sequence = 0; /* Back to zero */
}
context->last_timestamp = timestamp;
retval = ((timestamp - context->twepoch) << context->timestamp_left_shift)
| (context->datacenter_id << context->datacenter_id_shift)
| (worker_id << context->worker_id_shift)
| context->sequence;
spin_unlock(lock, pid);
//printf('%ld',retval);
srand((unsigned)retval);
//srand((unsigned) time(NULL ));
for (i = 0; i < length - 1; i++)
{
flag = rand() % 3;
switch (flag)
{
case 0:
string[i] = '1' + rand() % 5;
break;
case 1:
string[i] = '2' + rand() % 7;
break;
case 2:
string[i] = '0' + rand() % 10;
break;
default:
string[i] = '9';
break;
}
}
string[length - 1] = '\0';
RETURN_STRINGL(string,length,0);
}
C
1
https://gitee.com/xavier007/xukey.git
git@gitee.com:xavier007/xukey.git
xavier007
xukey
xukey
master

搜索帮助