1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/*
** OSSP uuid - Universally Unique Identifier
** Copyright (c) 2002-2005 Ralf S. Engelschall <rse@engelschall.com>
** Copyright (c) 2002-2005 The OSSP Project <http://www.ossp.org/>
**
** This file is part of OSSP uuid, a library for the generation
** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
*/
#ifndef __UI128_H__
#define __UI128_H__
#include <ctype.h>
#include <string.h>
#define UI128_BASE 256 /* 2^8 */
typedef struct {
uint8_t x[16]; /* 8*16 = 128 bit */
} ui128_t;
static ui128_t strtou128(const char * str, size_t strmax, const char ** end);
static void u128tostr(ui128_t x, char * str, size_t len);
static ui128_t ui128_addn(ui128_t x, int y, int * ov);
static ui128_t ui128_muln(ui128_t x, int y, int * ov);
static ui128_t ui128_divn(ui128_t x, int y, int * ov);
static int ui128_len(ui128_t x);
/* decode decimal digits to a 16-byte array */
static ui128_t strtou128(const char * str, size_t strmax, const char ** end) {
ui128_t z = {};
const char * cp = str;
for(int carry; cp != str + strmax && *cp >= '0' && *cp <= '9'; ++cp) {
z = ui128_muln(z, 10, &carry);
if(carry)
break;
z = ui128_addn(z, *cp - '0', &carry);
if(carry)
break;
}
*end = cp;
return z;
}
/* convert 16-byte array to decimal digits */
static void u128tostr(ui128_t x, char * str, size_t len) {
int n = ui128_len(x);
int i = 0;
do {
int r;
x = ui128_divn(x, 10, &r);
str[i++] = '0' + r;
while(n > 1 && x.x[n - 1] == 0)
n--;
} while(i < ((int)len - 1) && (n > 1 || x.x[0] != 0));
str[i] = '\0';
for(int j = 0; j < --i; ++j) {
char c = str[j];
str[j] = str[i];
str[i] = c;
}
}
/* addition of an ui128_t and a single digit */
static ui128_t ui128_addn(ui128_t x, int y, int * ov) {
ui128_t z;
for(size_t i = 0; i < sizeof(x.x); ++i) {
y += x.x[i];
z.x[i] = (y % UI128_BASE);
y /= UI128_BASE;
}
*ov = y;
return z;
}
static ui128_t ui128_muln(ui128_t x, int y, int * ov) {
ui128_t z;
int carry = 0;
for(size_t i = 0; i < sizeof(x.x); ++i) {
carry += (x.x[i] * y);
z.x[i] = (carry % UI128_BASE);
carry /= UI128_BASE;
}
*ov = carry;
return z;
}
static ui128_t ui128_divn(ui128_t x, int y, int * ov) {
ui128_t z;
unsigned carry = 0;
for(int i = (sizeof(x.x) - 1); i >= 0; --i) {
carry = (carry * UI128_BASE) + x.x[i];
z.x[i] = (carry / y);
carry %= y;
}
*ov = carry;
return z;
}
static int ui128_len(ui128_t x) {
int i;
for(i = sizeof(x.x); i > 1 && x.x[i - 1] == 0; --i)
;
return i;
}
#endif
|