1/*
2 *  printByteBuffer.c
3 *  byteutils
4 *
5 *  Created by Richard Murphy on 3/7/10.
6 *  Copyright 2010 McKenzie-Murphy. All rights reserved.
7 *
8 */
9
10#include "testbyteBuffer.h"
11#include <CommonCrypto/CommonRandomSPI.h>
12
13void printBytes(uint8_t *buff, size_t len, char *name)
14{
15	size_t i;
16	printf("Dumping %d bytes from %s\n", (int) len, name);
17	for(i=0; i<len; i++) {
18		if(i > 0 && !(i%8)) putchar(' ');
19		if(i > 0 && !(i%64)) putchar('\n');
20		printf("%02x", buff[i]);
21	}
22	putchar('\n');
23}
24
25void printByteBuffer(byteBuffer bb, char *name)
26{
27    printBytes(bb->bytes, bb->len, name);
28}
29
30
31byteBuffer
32mallocByteBuffer(size_t len)
33{
34	byteBuffer retval;
35	if((retval = (byteBuffer) malloc(sizeof(byteBufferStruct) + len + 1)) == NULL) return NULL;
36    retval->len = len;
37    retval->bytes = (uint8_t *) (retval + 1) ; /* just past the byteBuffer in malloc'ed space */
38    return retval;
39}
40
41size_t
42genRandomSize(size_t minSize, size_t maxSize)
43{
44    size_t randomInt;
45
46    if(minSize == maxSize) return minSize;
47
48    // make theSize > minSize < maxSize;
49    while(CCRandomCopyBytes(kCCRandomDefault, &randomInt, sizeof(uint32_t)) == -1) {
50        printf("got -1 from CCRandomCopyBytes\n");
51    }
52
53    randomInt = (randomInt % (maxSize - minSize)) + minSize;
54    return randomInt;
55}
56
57byteBuffer
58genRandomByteBuffer(size_t minSize, size_t maxSize)
59{
60	byteBuffer retval;
61    size_t randomInt;
62    CCCryptorStatus err;
63
64    randomInt = genRandomSize(minSize, maxSize);
65
66    retval = mallocByteBuffer(randomInt);
67    if(retval == NULL) return NULL;
68
69    if(retval->len != randomInt) return NULL;
70    bzero(retval->bytes, retval->len);
71
72    // fill bytes randomly
73    while((err = CCRandomCopyBytes(kCCRandomDefault, retval->bytes, retval->len)) != kCCSuccess) {
74        printf("got %d from CCRandomCopyBytes\n", err);
75    }
76
77    return retval;
78}
79
80/* utility function to convert hex character representation to their nibble (4 bit) values */
81static uint8_t
82nibbleFromChar(char c)
83{
84	if(c >= '0' && c <= '9') return c - '0';
85	if(c >= 'a' && c <= 'f') return c - 'a' + 10;
86	if(c >= 'A' && c <= 'F') return c - 'A' + 10;
87	return 255;
88}
89
90/* Convert a string of characters representing a hex buffer into a series of bytes of that real value */
91byteBuffer
92hexStringToBytes(const char *inhex)
93{
94	byteBuffer retval;
95	const uint8_t *p;
96	int len, i;
97
98    if(!inhex) len = 0;
99	else len = (int) strlen(inhex) / 2;
100
101	if((retval = mallocByteBuffer(len)) == NULL) return NULL;
102
103    if(inhex) {
104        for(i=0, p = (const uint8_t *) inhex; i<len; i++) {
105            retval->bytes[i] = (nibbleFromChar(*p) << 4) | nibbleFromChar(*(p+1));
106            p += 2;
107        }
108        retval->bytes[len] = 0;
109    } else
110        retval->bytes = NULL;
111	return retval;
112}
113
114
115
116byteBuffer
117bytesToBytes(void *bytes, size_t len)
118{
119    byteBuffer retval = mallocByteBuffer(len);
120    if(retval && bytes) memcpy(retval->bytes, bytes, len);
121    return retval;
122}
123
124int
125bytesAreEqual(byteBuffer b1, byteBuffer b2)
126{
127    if(b1->len != b2->len) return 0;
128    return (memcmp(b1->bytes, b2->bytes, b1->len) == 0);
129}
130
131
132static char byteMap[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
133static int byteMapLen = sizeof(byteMap);
134
135/* Utility function to convert nibbles (4 bit values) into a hex character representation */
136static char
137nibbleToChar(uint8_t nibble)
138{
139	if(nibble < byteMapLen) return byteMap[nibble];
140	return '*';
141}
142
143/* Convert a buffer of binary values into a hex string representation */
144char
145*bytesToHexString(byteBuffer bb)
146{
147	char *retval;
148	size_t i;
149
150	retval = malloc(bb->len*2 + 1);
151	for(i=0; i<bb->len; i++) {
152		retval[i*2] = nibbleToChar(bb->bytes[i] >> 4);
153		retval[i*2+1] = nibbleToChar(bb->bytes[i] & 0x0f);
154	}
155    retval[bb->len*2] = 0;
156	return retval;
157}
158
159char
160*bytesToHexStringWithSpaces(byteBuffer bb, int breaks)
161{
162	char *retval;
163	size_t i, j;
164
165    if(breaks == 0) {
166        return bytesToHexString(bb);
167    }
168
169    breaks /= 2;
170	retval = malloc(bb->len*2 + 1 + (bb->len*2 / breaks) + 10);
171	for(i=0, j=0; i<bb->len; i++, j+=2) {
172		retval[j] = nibbleToChar(bb->bytes[i] >> 4);
173		retval[j+1] = nibbleToChar(bb->bytes[i] & 0x0f);
174        if(((i+1) % breaks) == 0) {
175            retval[j+2] = ' ';
176            retval[j+3] = 0;
177            j++;
178        }
179	}
180	return retval;
181}
182
183
184