[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r20232 - in gnunet/src: include util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r20232 - in gnunet/src: include util |
Date: |
Sun, 4 Mar 2012 14:51:40 +0100 |
Author: grothoff
Date: 2012-03-04 14:51:40 +0100 (Sun, 04 Mar 2012)
New Revision: 20232
Modified:
gnunet/src/include/gnunet_crypto_lib.h
gnunet/src/util/crypto_hash.c
Log:
LRN: adding generic functions for conversion of binary data to ascii and back:
GNUNET_CRYPTO_string_to_data and GNUNET_CRYPTO_data_to_string
Modified: gnunet/src/include/gnunet_crypto_lib.h
===================================================================
--- gnunet/src/include/gnunet_crypto_lib.h 2012-03-04 01:24:44 UTC (rev
20231)
+++ gnunet/src/include/gnunet_crypto_lib.h 2012-03-04 13:51:40 UTC (rev
20232)
@@ -916,6 +916,39 @@
void
GNUNET_CRYPTO_random_disable_entropy_gathering (void);
+/**
+ * Convert binary data to ASCII encoding. The ASCII encoding is rather
+ * GNUnet specific. It was chosen such that it only uses characters
+ * in [0-9A-V], can be produced without complex arithmetics and uses a
+ * small number of characters. The GNUnet encoding uses 103 characters.
+ * Does not append 0-terminator, but returns a pointer to the place where
+ * it should be placed, if needed.
+ *
+ * @param data data to encode
+ * @param size size of data (in bytes)
+ * @param out buffer to fill
+ * @param out_size size of the buffer. Must be large enough to hold
+ * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5
+ * @return pointer to the next byte in 'out' or NULL on error.
+ */
+char *
+GNUNET_CRYPTO_data_to_string (unsigned char *data, size_t size,
+ char *out, size_t out_size);
+
+/**
+ * Convert ASCII encoding back to data
+ * out_size must match exactly the size of the data before it was encoded.
+ *
+ * @param enc the encoding
+ * @param enclen number of characters in 'enc' (without 0-terminator, which
can be missing)
+ * @param out location where to store the decoded data
+ * @param out_size sizeof the output buffer
+ * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
+ */
+int
+GNUNET_CRYPTO_string_to_data (const char *enc, size_t enclen,
+ unsigned char *out, size_t out_size);
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
Modified: gnunet/src/util/crypto_hash.c
===================================================================
--- gnunet/src/util/crypto_hash.c 2012-03-04 01:24:44 UTC (rev 20231)
+++ gnunet/src/util/crypto_hash.c 2012-03-04 13:51:40 UTC (rev 20232)
@@ -241,7 +241,6 @@
}
-
/* ***************** binary-ASCII encoding *************** */
/**
@@ -262,6 +261,124 @@
/**
+ * Convert binary data to ASCII encoding. The ASCII encoding is rather
+ * GNUnet specific. It was chosen such that it only uses characters
+ * in [0-9A-V], can be produced without complex arithmetics and uses a
+ * small number of characters. The GNUnet encoding uses 103 characters.
+ * Does not append 0-terminator, but returns a pointer to the place where
+ * it should be placed, if needed.
+ *
+ * @param data data to encode
+ * @param size size of data (in bytes)
+ * @param out buffer to fill
+ * @param out_size size of the buffer. Must be large enough to hold
+ * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 bytes
+ * @return pointer to the next byte in 'out' or NULL on error.
+ */
+char *
+GNUNET_CRYPTO_data_to_string (unsigned char *data, size_t size, char *out,
size_t out_size)
+{
+ /**
+ * 32 characters for encoding (GNUNET_CRYPTO_hash => 32 characters)
+ */
+ static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+ unsigned int wpos;
+ unsigned int rpos;
+ unsigned int bits;
+ unsigned int vbit;
+
+ GNUNET_assert (data != NULL);
+ GNUNET_assert (out != NULL);
+ GNUNET_assert (out_size >= (((size*8) + ((size*8) % 5)) % 5));
+ vbit = 0;
+ wpos = 0;
+ rpos = 0;
+ bits = 0;
+ while ((rpos < size) || (vbit > 0))
+ {
+ if ((rpos < size) && (vbit < 5))
+ {
+ bits = (bits << 8) | data[rpos++]; /* eat 8 more bits */
+ vbit += 8;
+ }
+ if (vbit < 5)
+ {
+ bits <<= (5 - vbit); /* zero-padding */
+ GNUNET_assert (vbit == ((size * 8) % 5));
+ vbit = 5;
+ }
+ if (wpos >= out_size)
+ return NULL;
+ out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
+ vbit -= 5;
+ }
+ if (wpos != out_size)
+ return NULL;
+ GNUNET_assert (vbit == 0);
+ return &out[wpos];
+}
+
+
+/**
+ * Convert ASCII encoding back to data
+ * out_size must match exactly the size of the data before it was encoded.
+ *
+ * @param enc the encoding
+ * @param enclen number of characters in 'enc' (without 0-terminator, which
can be missing)
+ * @param out location where to store the decoded data
+ * @param out_size sizeof the output buffer
+ * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding
+ */
+int
+GNUNET_CRYPTO_string_to_data (const char *enc, size_t enclen,
+ unsigned char *out, size_t out_size)
+{
+ unsigned int rpos;
+ unsigned int wpos;
+ unsigned int bits;
+ unsigned int vbit;
+ int ret;
+ int shift;
+ int encoded_len = out_size * 8;
+ if (encoded_len % 5 > 0)
+ {
+ vbit = encoded_len % 5; /* padding! */
+ shift = 5 - vbit;
+ }
+ else
+ {
+ vbit = 0;
+ shift = 0;
+ }
+ if ((encoded_len + shift) / 5 != enclen)
+ return GNUNET_SYSERR;
+
+ wpos = out_size;
+ rpos = enclen;
+ bits = (ret = getValue__ (enc[--rpos])) >> (5 - encoded_len % 5);
+ if (-1 == ret)
+ return GNUNET_SYSERR;
+ while (wpos > 0)
+ {
+ GNUNET_assert (rpos > 0);
+ bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits;
+ if (-1 == ret)
+ return GNUNET_SYSERR;
+ vbit += 5;
+ if (vbit >= 8)
+ {
+ out[--wpos] = (unsigned char) bits;
+ bits >>= 8;
+ vbit -= 8;
+ }
+ }
+ GNUNET_assert (rpos == 0);
+ GNUNET_assert (vbit == 0);
+ return GNUNET_OK;
+}
+
+
+/**
* Convert GNUNET_CRYPTO_hash to ASCII encoding. The ASCII encoding is rather
* GNUnet specific. It was chosen such that it only uses characters
* in [0-9A-V], can be produced without complex arithmetics and uses a
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r20232 - in gnunet/src: include util,
gnunet <=