Pieter Wuille
13 years ago
3 changed files with 371 additions and 0 deletions
@ -0,0 +1,63 @@ |
|||||||
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
#ifndef _BITCOIN_COMPAT_H |
||||||
|
#define _BITCOIN_COMPAT_H 1 |
||||||
|
|
||||||
|
#ifdef WIN32 |
||||||
|
#define _WIN32_WINNT 0x0501 |
||||||
|
#define WIN32_LEAN_AND_MEAN 1 |
||||||
|
#ifndef NOMINMAX |
||||||
|
#define NOMINMAX |
||||||
|
#endif |
||||||
|
#include <winsock2.h> |
||||||
|
#include <mswsock.h> |
||||||
|
#include <ws2tcpip.h> |
||||||
|
#else |
||||||
|
#include <sys/types.h> |
||||||
|
#include <sys/socket.h> |
||||||
|
#include <sys/fcntl.h> |
||||||
|
#include <arpa/inet.h> |
||||||
|
#include <netdb.h> |
||||||
|
#include <net/if.h> |
||||||
|
#include <netinet/in.h> |
||||||
|
#include <ifaddrs.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef u_int SOCKET; |
||||||
|
#ifdef WIN32 |
||||||
|
#define MSG_NOSIGNAL 0 |
||||||
|
#define MSG_DONTWAIT 0 |
||||||
|
typedef int socklen_t; |
||||||
|
#else |
||||||
|
#include "errno.h" |
||||||
|
#define WSAGetLastError() errno |
||||||
|
#define WSAEINVAL EINVAL |
||||||
|
#define WSAEALREADY EALREADY |
||||||
|
#define WSAEWOULDBLOCK EWOULDBLOCK |
||||||
|
#define WSAEMSGSIZE EMSGSIZE |
||||||
|
#define WSAEINTR EINTR |
||||||
|
#define WSAEINPROGRESS EINPROGRESS |
||||||
|
#define WSAEADDRINUSE EADDRINUSE |
||||||
|
#define WSAENOTSOCK EBADF |
||||||
|
#define INVALID_SOCKET (SOCKET)(~0) |
||||||
|
#define SOCKET_ERROR -1 |
||||||
|
#endif |
||||||
|
|
||||||
|
inline int myclosesocket(SOCKET& hSocket) |
||||||
|
{ |
||||||
|
if (hSocket == INVALID_SOCKET) |
||||||
|
return WSAENOTSOCK; |
||||||
|
#ifdef WIN32 |
||||||
|
int ret = closesocket(hSocket); |
||||||
|
#else |
||||||
|
int ret = close(hSocket); |
||||||
|
#endif |
||||||
|
hSocket = INVALID_SOCKET; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
#define closesocket(s) myclosesocket(s) |
||||||
|
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,90 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||||
|
*/ |
||||||
|
#ifndef BITCOIN_STRLCPY_H |
||||||
|
#define BITCOIN_STRLCPY_H |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy src to string dst of size siz. At most siz-1 characters |
||||||
|
* will be copied. Always NUL terminates (unless siz == 0). |
||||||
|
* Returns strlen(src); if retval >= siz, truncation occurred. |
||||||
|
*/ |
||||||
|
inline size_t strlcpy(char *dst, const char *src, size_t siz) |
||||||
|
{ |
||||||
|
char *d = dst; |
||||||
|
const char *s = src; |
||||||
|
size_t n = siz; |
||||||
|
|
||||||
|
/* Copy as many bytes as will fit */ |
||||||
|
if (n != 0) |
||||||
|
{ |
||||||
|
while (--n != 0) |
||||||
|
{ |
||||||
|
if ((*d++ = *s++) == '\0') |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Not enough room in dst, add NUL and traverse rest of src */ |
||||||
|
if (n == 0) |
||||||
|
{ |
||||||
|
if (siz != 0) |
||||||
|
*d = '\0'; /* NUL-terminate dst */ |
||||||
|
while (*s++) |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
return(s - src - 1); /* count does not include NUL */ |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Appends src to string dst of size siz (unlike strncat, siz is the |
||||||
|
* full size of dst, not space left). At most siz-1 characters |
||||||
|
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). |
||||||
|
* Returns strlen(src) + MIN(siz, strlen(initial dst)). |
||||||
|
* If retval >= siz, truncation occurred. |
||||||
|
*/ |
||||||
|
inline size_t strlcat(char *dst, const char *src, size_t siz) |
||||||
|
{ |
||||||
|
char *d = dst; |
||||||
|
const char *s = src; |
||||||
|
size_t n = siz; |
||||||
|
size_t dlen; |
||||||
|
|
||||||
|
/* Find the end of dst and adjust bytes left but don't go past end */ |
||||||
|
while (n-- != 0 && *d != '\0') |
||||||
|
d++; |
||||||
|
dlen = d - dst; |
||||||
|
n = siz - dlen; |
||||||
|
|
||||||
|
if (n == 0) |
||||||
|
return(dlen + strlen(s)); |
||||||
|
while (*s != '\0') |
||||||
|
{ |
||||||
|
if (n != 1) |
||||||
|
{ |
||||||
|
*d++ = *s; |
||||||
|
n--; |
||||||
|
} |
||||||
|
s++; |
||||||
|
} |
||||||
|
*d = '\0'; |
||||||
|
|
||||||
|
return(dlen + (s - src)); /* count does not include NUL */ |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,218 @@ |
|||||||
|
#include <stdio.h> |
||||||
|
#include "util.h" |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
string vstrprintf(const std::string &format, va_list ap) |
||||||
|
{ |
||||||
|
char buffer[50000]; |
||||||
|
char* p = buffer; |
||||||
|
int limit = sizeof(buffer); |
||||||
|
int ret; |
||||||
|
loop |
||||||
|
{ |
||||||
|
va_list arg_ptr; |
||||||
|
va_copy(arg_ptr, ap); |
||||||
|
ret = vsnprintf(p, limit, format.c_str(), arg_ptr); |
||||||
|
va_end(arg_ptr); |
||||||
|
if (ret >= 0 && ret < limit) |
||||||
|
break; |
||||||
|
if (p != buffer) |
||||||
|
delete[] p; |
||||||
|
limit *= 2; |
||||||
|
p = new char[limit]; |
||||||
|
if (p == NULL) |
||||||
|
throw std::bad_alloc(); |
||||||
|
} |
||||||
|
string str(p, p+ret); |
||||||
|
if (p != buffer) |
||||||
|
delete[] p; |
||||||
|
return str; |
||||||
|
} |
||||||
|
|
||||||
|
string EncodeBase32(const unsigned char* pch, size_t len) |
||||||
|
{ |
||||||
|
static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; |
||||||
|
|
||||||
|
string strRet=""; |
||||||
|
strRet.reserve((len+4)/5*8); |
||||||
|
|
||||||
|
int mode=0, left=0; |
||||||
|
const unsigned char *pchEnd = pch+len; |
||||||
|
|
||||||
|
while (pch<pchEnd) |
||||||
|
{ |
||||||
|
int enc = *(pch++); |
||||||
|
switch (mode) |
||||||
|
{ |
||||||
|
case 0: // we have no bits
|
||||||
|
strRet += pbase32[enc >> 3]; |
||||||
|
left = (enc & 7) << 2; |
||||||
|
mode = 1; |
||||||
|
break; |
||||||
|
|
||||||
|
case 1: // we have three bits
|
||||||
|
strRet += pbase32[left | (enc >> 6)]; |
||||||
|
strRet += pbase32[(enc >> 1) & 31]; |
||||||
|
left = (enc & 1) << 4; |
||||||
|
mode = 2; |
||||||
|
break; |
||||||
|
|
||||||
|
case 2: // we have one bit
|
||||||
|
strRet += pbase32[left | (enc >> 4)]; |
||||||
|
left = (enc & 15) << 1; |
||||||
|
mode = 3; |
||||||
|
break; |
||||||
|
|
||||||
|
case 3: // we have four bits
|
||||||
|
strRet += pbase32[left | (enc >> 7)]; |
||||||
|
strRet += pbase32[(enc >> 2) & 31]; |
||||||
|
left = (enc & 3) << 3; |
||||||
|
mode = 4; |
||||||
|
break; |
||||||
|
|
||||||
|
case 4: // we have two bits
|
||||||
|
strRet += pbase32[left | (enc >> 5)]; |
||||||
|
strRet += pbase32[enc & 31]; |
||||||
|
mode = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static const int nPadding[5] = {0, 6, 4, 3, 1}; |
||||||
|
if (mode) |
||||||
|
{ |
||||||
|
strRet += pbase32[left]; |
||||||
|
for (int n=0; n<nPadding[mode]; n++) |
||||||
|
strRet += '='; |
||||||
|
} |
||||||
|
|
||||||
|
return strRet; |
||||||
|
} |
||||||
|
|
||||||
|
string EncodeBase32(const string& str) |
||||||
|
{ |
||||||
|
return EncodeBase32((const unsigned char*)str.c_str(), str.size()); |
||||||
|
} |
||||||
|
|
||||||
|
vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid) |
||||||
|
{ |
||||||
|
static const int decode32_table[256] = |
||||||
|
{ |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, 0, 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, -1, -1, -1, -1, -1, -1, 0, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 |
||||||
|
}; |
||||||
|
|
||||||
|
if (pfInvalid) |
||||||
|
*pfInvalid = false; |
||||||
|
|
||||||
|
vector<unsigned char> vchRet; |
||||||
|
vchRet.reserve((strlen(p))*5/8); |
||||||
|
|
||||||
|
int mode = 0; |
||||||
|
int left = 0; |
||||||
|
|
||||||
|
while (1) |
||||||
|
{ |
||||||
|
int dec = decode32_table[(unsigned char)*p]; |
||||||
|
if (dec == -1) break; |
||||||
|
p++; |
||||||
|
switch (mode) |
||||||
|
{ |
||||||
|
case 0: // we have no bits and get 5
|
||||||
|
left = dec; |
||||||
|
mode = 1; |
||||||
|
break; |
||||||
|
|
||||||
|
case 1: // we have 5 bits and keep 2
|
||||||
|
vchRet.push_back((left<<3) | (dec>>2)); |
||||||
|
left = dec & 3; |
||||||
|
mode = 2; |
||||||
|
break; |
||||||
|
|
||||||
|
case 2: // we have 2 bits and keep 7
|
||||||
|
left = left << 5 | dec; |
||||||
|
mode = 3; |
||||||
|
break; |
||||||
|
|
||||||
|
case 3: // we have 7 bits and keep 4
|
||||||
|
vchRet.push_back((left<<1) | (dec>>4)); |
||||||
|
left = dec & 15; |
||||||
|
mode = 4; |
||||||
|
break; |
||||||
|
|
||||||
|
case 4: // we have 4 bits, and keep 1
|
||||||
|
vchRet.push_back((left<<4) | (dec>>1)); |
||||||
|
left = dec & 1; |
||||||
|
mode = 5; |
||||||
|
break; |
||||||
|
|
||||||
|
case 5: // we have 1 bit, and keep 6
|
||||||
|
left = left << 5 | dec; |
||||||
|
mode = 6; |
||||||
|
break; |
||||||
|
|
||||||
|
case 6: // we have 6 bits, and keep 3
|
||||||
|
vchRet.push_back((left<<2) | (dec>>3)); |
||||||
|
left = dec & 7; |
||||||
|
mode = 7; |
||||||
|
break; |
||||||
|
|
||||||
|
case 7: // we have 3 bits, and keep 0
|
||||||
|
vchRet.push_back((left<<5) | dec); |
||||||
|
mode = 0; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (pfInvalid) |
||||||
|
switch (mode) |
||||||
|
{ |
||||||
|
case 0: // 8n base32 characters processed: ok
|
||||||
|
break; |
||||||
|
|
||||||
|
case 1: // 8n+1 base32 characters processed: impossible
|
||||||
|
case 3: // +3
|
||||||
|
case 6: // +6
|
||||||
|
*pfInvalid = true; |
||||||
|
break; |
||||||
|
|
||||||
|
case 2: // 8n+2 base32 characters processed: require '======'
|
||||||
|
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) |
||||||
|
*pfInvalid = true; |
||||||
|
break; |
||||||
|
|
||||||
|
case 4: // 8n+4 base32 characters processed: require '===='
|
||||||
|
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) |
||||||
|
*pfInvalid = true; |
||||||
|
break; |
||||||
|
|
||||||
|
case 5: // 8n+5 base32 characters processed: require '==='
|
||||||
|
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) |
||||||
|
*pfInvalid = true; |
||||||
|
break; |
||||||
|
|
||||||
|
case 7: // 8n+7 base32 characters processed: require '='
|
||||||
|
if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) |
||||||
|
*pfInvalid = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
return vchRet; |
||||||
|
} |
||||||
|
|
||||||
|
string DecodeBase32(const string& str) |
||||||
|
{ |
||||||
|
vector<unsigned char> vchRet = DecodeBase32(str.c_str()); |
||||||
|
return string((const char*)&vchRet[0], vchRet.size()); |
||||||
|
} |
Loading…
Reference in new issue