diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-12-06 21:51:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-12-06 21:51:01 +0000 |
commit | 6332c8ffbc8f63a8006a3283b95f3e3abae1e8db (patch) | |
tree | 3544b50f45560c21ea14144b99286ae8e4c4a5c1 /src/util | |
parent | ea70f894ce5dc62a840a507405724a55e452d033 (diff) | |
download | gnunet-6332c8ffbc8f63a8006a3283b95f3e3abae1e8db.tar.gz gnunet-6332c8ffbc8f63a8006a3283b95f3e3abae1e8db.zip |
-move base64 encoder/decoder to util
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/strings.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/util/strings.c b/src/util/strings.c index 85c6a1cc6..70a1160dd 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -1743,4 +1743,144 @@ GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX) | |||
1743 | } | 1743 | } |
1744 | 1744 | ||
1745 | 1745 | ||
1746 | |||
1747 | /** ******************** Base64 encoding ***********/ | ||
1748 | |||
1749 | #define FILLCHAR '=' | ||
1750 | static char *cvt = | ||
1751 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; | ||
1752 | |||
1753 | |||
1754 | /** | ||
1755 | * Encode into Base64. | ||
1756 | * | ||
1757 | * @param data the data to encode | ||
1758 | * @param len the length of the input | ||
1759 | * @param output where to write the output (*output should be NULL, | ||
1760 | * is allocated) | ||
1761 | * @return the size of the output | ||
1762 | */ | ||
1763 | size_t | ||
1764 | GNUNET_STRINGS_base64_encode (const char *data, | ||
1765 | size_t len, | ||
1766 | char **output) | ||
1767 | { | ||
1768 | size_t i; | ||
1769 | char c; | ||
1770 | size_t ret; | ||
1771 | char *opt; | ||
1772 | |||
1773 | ret = 0; | ||
1774 | opt = GNUNET_malloc (2 + (len * 4 / 3) + 8); | ||
1775 | *output = opt; | ||
1776 | for (i = 0; i < len; ++i) | ||
1777 | { | ||
1778 | c = (data[i] >> 2) & 0x3f; | ||
1779 | opt[ret++] = cvt[(int) c]; | ||
1780 | c = (data[i] << 4) & 0x3f; | ||
1781 | if (++i < len) | ||
1782 | c |= (data[i] >> 4) & 0x0f; | ||
1783 | opt[ret++] = cvt[(int) c]; | ||
1784 | if (i < len) | ||
1785 | { | ||
1786 | c = (data[i] << 2) & 0x3f; | ||
1787 | if (++i < len) | ||
1788 | c |= (data[i] >> 6) & 0x03; | ||
1789 | opt[ret++] = cvt[(int) c]; | ||
1790 | } | ||
1791 | else | ||
1792 | { | ||
1793 | ++i; | ||
1794 | opt[ret++] = FILLCHAR; | ||
1795 | } | ||
1796 | if (i < len) | ||
1797 | { | ||
1798 | c = data[i] & 0x3f; | ||
1799 | opt[ret++] = cvt[(int) c]; | ||
1800 | } | ||
1801 | else | ||
1802 | { | ||
1803 | opt[ret++] = FILLCHAR; | ||
1804 | } | ||
1805 | } | ||
1806 | opt[ret++] = FILLCHAR; | ||
1807 | return ret; | ||
1808 | } | ||
1809 | |||
1810 | #define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\ | ||
1811 | :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\ | ||
1812 | :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\ | ||
1813 | :((a) == '+') ? 62\ | ||
1814 | :((a) == '/') ? 63 : -1) | ||
1815 | |||
1816 | |||
1817 | /** | ||
1818 | * Decode from Base64. | ||
1819 | * | ||
1820 | * @param data the data to encode | ||
1821 | * @param len the length of the input | ||
1822 | * @param output where to write the output (*output should be NULL, | ||
1823 | * is allocated) | ||
1824 | * @return the size of the output | ||
1825 | */ | ||
1826 | size_t | ||
1827 | GNUNET_STRINGS_base64_decode (const char *data, | ||
1828 | size_t len, char **output) | ||
1829 | { | ||
1830 | size_t i; | ||
1831 | char c; | ||
1832 | char c1; | ||
1833 | size_t ret = 0; | ||
1834 | |||
1835 | #define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\ | ||
1836 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "ignoring CR/LF\n"); \ | ||
1837 | i++; \ | ||
1838 | if (i >= len) goto END; \ | ||
1839 | } | ||
1840 | |||
1841 | *output = GNUNET_malloc ((len * 3 / 4) + 8); | ||
1842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1843 | "base64_decode decoding len=%d\n", | ||
1844 | (int) len); | ||
1845 | for (i = 0; i < len; ++i) | ||
1846 | { | ||
1847 | CHECK_CRLF; | ||
1848 | if (FILLCHAR == data[i]) | ||
1849 | break; | ||
1850 | c = (char) cvtfind (data[i]); | ||
1851 | ++i; | ||
1852 | CHECK_CRLF; | ||
1853 | c1 = (char) cvtfind (data[i]); | ||
1854 | c = (c << 2) | ((c1 >> 4) & 0x3); | ||
1855 | (*output)[ret++] = c; | ||
1856 | if (++i < len) | ||
1857 | { | ||
1858 | CHECK_CRLF; | ||
1859 | c = data[i]; | ||
1860 | if (FILLCHAR == c) | ||
1861 | break; | ||
1862 | c = (char) cvtfind (c); | ||
1863 | c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf); | ||
1864 | (*output)[ret++] = c1; | ||
1865 | } | ||
1866 | if (++i < len) | ||
1867 | { | ||
1868 | CHECK_CRLF; | ||
1869 | c1 = data[i]; | ||
1870 | if (FILLCHAR == c1) | ||
1871 | break; | ||
1872 | |||
1873 | c1 = (char) cvtfind (c1); | ||
1874 | c = ((c << 6) & 0xc0) | c1; | ||
1875 | (*output)[ret++] = c; | ||
1876 | } | ||
1877 | } | ||
1878 | END: | ||
1879 | return ret; | ||
1880 | } | ||
1881 | |||
1882 | |||
1883 | |||
1884 | |||
1885 | |||
1746 | /* end of strings.c */ | 1886 | /* end of strings.c */ |