base64url/ 0000755 0001762 0000144 00000000000 13276256704 012075 5 ustar ligges users base64url/inst/ 0000755 0001762 0000144 00000000000 13117715153 013042 5 ustar ligges users base64url/inst/doc/ 0000755 0001762 0000144 00000000000 13276254703 013614 5 ustar ligges users base64url/inst/doc/Benchmarks.Rmd 0000644 0001762 0000144 00000005103 13250515635 016330 0 ustar ligges users ---
title: "Benchmark"
author: "Michel Lang"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Benchmark}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r,include=FALSE,cache=FALSE}
do.eval = requireNamespace("microbenchmark", quietly = TRUE)
```
This small benchmark compares the performance of the base64 encoding/decoding in package `base64url` with the implementations in the packages [`base64enc`](https://cran.r-project.org/package=base64enc) and [`openssl`](https://cran.r-project.org/package=openssl).
## Encoding of a single string
```{r, eval=do.eval}
library(base64url)
library(base64enc)
library(openssl)
library(microbenchmark)
x = "plain text"
microbenchmark(
base64url = base64_urlencode(x),
base64enc = base64encode(charToRaw(x)),
openssl = base64_encode(x)
)
```
## Decoding of a single string
```{r, eval = do.eval}
x = "N0JBLlRaUTp1bi5KOW4xWStNWEJoLHRQaDZ3"
microbenchmark(
base64url = base64_urldecode(x),
base64enc = rawToChar(base64decode(x)),
openssl = rawToChar(base64_decode(x))
)
```
## Encoding and decoding of character vectors
Here, the task has changed from encoding/decoding a single string to processing multiple strings stored inside a character vector.
First, we create a small utility function which returns `n` random strings with a random number of characters (between 1 and 32) each.
```{r, eval = do.eval}
rand = function(n, min = 1, max = 32) {
chars = c(letters, LETTERS, as.character(0:9), c(".", ":", ",", "+", "-", "*", "/"))
replicate(n, paste0(sample(chars, sample(min:max, 1), replace = TRUE), collapse = ""))
}
set.seed(1)
rand(10)
```
Only `base64url` is vectorized for string input, the alternative implementations need wrappers to process character vectors:
```{r, eval = do.eval}
base64enc_encode = function(x) {
vapply(x, function(x) base64encode(charToRaw(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_encode = function(x) {
vapply(x, function(x) base64_encode(x), NA_character_, USE.NAMES = FALSE)
}
base64enc_decode = function(x) {
vapply(x, function(x) rawToChar(base64decode(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_decode = function(x) {
vapply(x, function(x) rawToChar(base64_decode(x)), NA_character_, USE.NAMES = FALSE)
}
```
The following benchmark measures the runtime to encode 1000 random strings and then decode them again:
```{r, eval = do.eval}
set.seed(1)
x = rand(1000)
microbenchmark(
base64url = base64_urldecode(base64_urlencode(x)),
base64enc = base64enc_decode(base64enc_encode(x)),
openssl = openssl_decode(openssl_encode(x))
)
```
base64url/inst/doc/Benchmarks.html 0000644 0001762 0000144 00000040672 13276254703 016570 0 ustar ligges users
Benchmark
Benchmark
Michel Lang
2018-05-14
This small benchmark compares the performance of the base64 encoding/decoding in package base64url
with the implementations in the packages base64enc
and openssl
.
Encoding of a single string
## Unit: nanoseconds
## expr min lq mean median uq max neval
## base64url 408 461.5 853.52 698.0 782.5 20430 100
## base64enc 1199 1367.0 3114.89 1865.0 1983.5 139937 100
## openssl 13188 13536.0 15256.11 13749.5 14081.5 135871 100
Decoding of a single string
## Unit: nanoseconds
## expr min lq mean median uq max neval
## base64url 423 485.0 1104.57 655.5 923 40442 100
## base64enc 1504 1681.5 2879.92 2225.5 2546 76432 100
## openssl 19066 19643.0 21264.27 19915.5 20281 119636 100
Encoding and decoding of character vectors
Here, the task has changed from encoding/decoding a single string to processing multiple strings stored inside a character vector. First, we create a small utility function which returns n
random strings with a random number of characters (between 1 and 32) each.
rand = function(n, min = 1, max = 32) {
chars = c(letters, LETTERS, as.character(0:9), c(".", ":", ",", "+", "-", "*", "/"))
replicate(n, paste0(sample(chars, sample(min:max, 1), replace = TRUE), collapse = ""))
}
set.seed(1)
rand(10)
## [1] "zN.n9+TRe" "mVA1IX/"
## [3] "1,oSisAaA8xHP" "m5U2hXC4S2MK2bGY"
## [5] "G7EqegvJTC.uFwSrH0f8x5x" "G97A1-DXBw0"
## [7] "XiqjqeS" "13FC3PTys/RoiG:P*YyDkaXhES/IH"
## [9] "0FJopP" "fcS,PMK*JVPqrYFmZh7"
Only base64url
is vectorized for string input, the alternative implementations need wrappers to process character vectors:
base64enc_encode = function(x) {
vapply(x, function(x) base64encode(charToRaw(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_encode = function(x) {
vapply(x, function(x) base64_encode(x), NA_character_, USE.NAMES = FALSE)
}
base64enc_decode = function(x) {
vapply(x, function(x) rawToChar(base64decode(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_decode = function(x) {
vapply(x, function(x) rawToChar(base64_decode(x)), NA_character_, USE.NAMES = FALSE)
}
The following benchmark measures the runtime to encode 1000 random strings and then decode them again:
## Unit: microseconds
## expr min lq mean median uq max
## base64url 214.031 222.0655 270.415 260.3725 311.967 441.127
## base64enc 3613.444 3974.8940 4228.395 4058.2495 4157.485 11094.540
## openssl 34166.572 35453.3810 36002.175 35794.9835 36349.533 42507.878
## neval
## 100
## 100
## 100
base64url/inst/doc/Benchmarks.R 0000644 0001762 0000144 00000003450 13276254702 016015 0 ustar ligges users ## ----include=FALSE,cache=FALSE-------------------------------------------
do.eval = requireNamespace("microbenchmark", quietly = TRUE)
## ---- eval=do.eval-------------------------------------------------------
library(base64url)
library(base64enc)
library(openssl)
library(microbenchmark)
x = "plain text"
microbenchmark(
base64url = base64_urlencode(x),
base64enc = base64encode(charToRaw(x)),
openssl = base64_encode(x)
)
## ---- eval = do.eval-----------------------------------------------------
x = "N0JBLlRaUTp1bi5KOW4xWStNWEJoLHRQaDZ3"
microbenchmark(
base64url = base64_urldecode(x),
base64enc = rawToChar(base64decode(x)),
openssl = rawToChar(base64_decode(x))
)
## ---- eval = do.eval-----------------------------------------------------
rand = function(n, min = 1, max = 32) {
chars = c(letters, LETTERS, as.character(0:9), c(".", ":", ",", "+", "-", "*", "/"))
replicate(n, paste0(sample(chars, sample(min:max, 1), replace = TRUE), collapse = ""))
}
set.seed(1)
rand(10)
## ---- eval = do.eval-----------------------------------------------------
base64enc_encode = function(x) {
vapply(x, function(x) base64encode(charToRaw(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_encode = function(x) {
vapply(x, function(x) base64_encode(x), NA_character_, USE.NAMES = FALSE)
}
base64enc_decode = function(x) {
vapply(x, function(x) rawToChar(base64decode(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_decode = function(x) {
vapply(x, function(x) rawToChar(base64_decode(x)), NA_character_, USE.NAMES = FALSE)
}
## ---- eval = do.eval-----------------------------------------------------
set.seed(1)
x = rand(1000)
microbenchmark(
base64url = base64_urldecode(base64_urlencode(x)),
base64enc = base64enc_decode(base64enc_encode(x)),
openssl = openssl_decode(openssl_encode(x))
)
base64url/tests/ 0000755 0001762 0000144 00000000000 13250475371 013232 5 ustar ligges users base64url/tests/testthat.R 0000644 0001762 0000144 00000000076 13250475371 015220 0 ustar ligges users library(testthat)
library(base64url)
test_check("base64url")
base64url/tests/testthat/ 0000755 0001762 0000144 00000000000 13276256704 015077 5 ustar ligges users base64url/tests/testthat/test_base32.R 0000644 0001762 0000144 00000003231 13250515635 017330 0 ustar ligges users context("base32")
test_that("encode and decode on random strings", {
for (i in 1:10) {
plain = rand(1000)
enc = base32_encode(plain, use.padding = TRUE)
expect_character(enc, any.missing = FALSE, len = length(plain), pattern = "^[A-Z234567=]+$")
unenc = base32_decode(enc, use.padding = TRUE)
expect_character(unenc, any.missing = FALSE, len = length(plain), min.chars = 1L)
expect_equal(plain, unenc)
}
})
test_that("unexpected input", {
expect_identical(base32_encode("", use.padding = TRUE), "")
expect_identical(base32_decode("", use.padding = TRUE), "")
expect_identical(base32_encode(NA_character_, use.padding = TRUE), NA_character_)
expect_identical(base32_decode(NA_character_, use.padding = TRUE), NA_character_)
expect_identical(base32_encode(character(0), use.padding = TRUE), character(0))
expect_identical(base32_decode(character(0), use.padding = TRUE), character(0))
expect_error(base32_encode(NA, use.padding = TRUE), "character vector")
expect_error(base32_decode(NA, use.padding = TRUE), "character vector")
expect_identical(base32_encode("", use.padding = FALSE), "")
expect_identical(base32_decode("", use.padding = FALSE), "")
expect_identical(base32_encode(NA_character_, use.padding = FALSE), NA_character_)
expect_identical(base32_decode(NA_character_, use.padding = FALSE), NA_character_)
expect_identical(base32_encode(character(0), use.padding = FALSE), character(0))
expect_identical(base32_decode(character(0), use.padding = FALSE), character(0))
expect_error(base32_encode(NA, use.padding = FALSE), "character vector")
expect_error(base32_decode(NA, use.padding = FALSE), "character vector")
})
base64url/tests/testthat/helper.R 0000644 0001762 0000144 00000000540 13274032514 016465 0 ustar ligges users library(testthat)
library(checkmate)
rand = function(n, min = 5L, max = 50L, only.ascii = FALSE) {
chars = c(letters, LETTERS, c("=", "+", "-", "_", "/", "&", "=", "?", ":", ".", "%"))
if (!isTRUE(only.ascii))
chars = c(chars, "ö", "`", "\n", "♏")
replicate(n, paste0(sample(chars, sample(min:max, 1L), replace = TRUE), collapse = ""))
}
base64url/tests/testthat/test_base64.R 0000644 0001762 0000144 00000007002 13274541441 017335 0 ustar ligges users context("base64url")
requireNamespace("base64enc", quietly = TRUE)
is_utf8 = function() {
grepl("utf-?8", Sys.getlocale("LC_CTYPE"), ignore.case = TRUE)
}
convert_to_url = function(x) {
x = gsub("/", "_", x, fixed = TRUE)
x = gsub("+", "-", x, fixed = TRUE)
gsub("=+$", "", x)
}
convert_to_rfc = function(x) {
x = gsub("_", "/", x, fixed = TRUE)
x = gsub("-", "+", x, fixed = TRUE)
pad = nchar(x) %% 4
paste0(x, strrep("=", ifelse(pad == 0L, 0L, 4L - pad)))
}
base64enc_rfc = function(x) {
vapply(x, function(x) base64enc::base64encode(charToRaw(x)), NA_character_, USE.NAMES = FALSE)
}
base64dec_rfc = function(x) {
vapply(x, function(x) rawToChar(base64enc::base64decode(x)), NA_character_, USE.NAMES = FALSE)
}
base64enc_openssl = function(x) {
vapply(x, function(x) openssl::base64_encode(x), NA_character_, USE.NAMES = FALSE)
}
base64dec_openssl = function(x) {
vapply(x, function(x) rawToChar(openssl::base64_decode(x)), NA_character_, USE.NAMES = FALSE)
}
test_that("encode and decode on random strings", {
for (i in 1:10) {
plain = rand(1000)
enc = base64_urlencode(plain)
expect_character(enc, any.missing = FALSE, len = length(plain), pattern = "^[[:alnum:]_-]+$")
unenc = base64_urldecode(enc)
expect_character(unenc, any.missing = FALSE, len = length(plain), min.chars = 1L)
expect_equal(plain, unenc)
}
})
test_that("comparison with base64enc", {
for (i in 1:10) {
# base64enc seems to have problems with the encoding :/
# rfc <-> rfc is not working!
plain = rand(1000, only.ascii = testOS("windows") || !is_utf8())
enc_rfc = base64enc_rfc(plain)
enc_url = base64_urlencode(plain)
# do we get plain back?
expect_equal(plain, base64_urldecode(enc_url), label = "url <-> url works")
expect_equal(plain, base64dec_rfc(enc_rfc), label = "rfc <-> rfc works")
# do we get the same encoding as rfc?
expect_equal(enc_url, convert_to_url(enc_rfc))
expect_equal(enc_rfc, convert_to_rfc(enc_url))
# do we get the same decodings after conversion?
expect_equal(plain, base64_urldecode(convert_to_url(enc_rfc)))
expect_equal(plain, base64dec_rfc(convert_to_rfc(enc_url)))
}
})
test_that("comparison with openssl", {
for (i in 1:10) {
# openssl seems to have problems with the encoding on windows :/
# openssl <-> openssl is not working!
plain = rand(1000, only.ascii = testOS("windows") || !is_utf8())
enc_openssl = base64enc_openssl(plain)
enc_url = base64_urlencode(plain)
# do we get plain back?
expect_equal(plain, base64_urldecode(enc_url), label = "url <-> url works")
expect_equal(plain, base64dec_openssl(enc_openssl), label = "openssl <-> openssl works")
# do we get the same encoding as openssl?
expect_equal(enc_url, convert_to_url(enc_openssl))
expect_equal(enc_openssl, convert_to_rfc(enc_url))
# do we get the same decodings after conversion?
expect_equal(plain, base64_urldecode(convert_to_url(enc_openssl)))
expect_equal(plain, base64dec_openssl(convert_to_rfc(enc_url)))
}
})
test_that("unexpected input", {
expect_identical(base64_urlencode(""), "")
expect_identical(base64_urldecode(""), "")
expect_identical(base64_urlencode(NA_character_), NA_character_)
expect_identical(base64_urldecode(NA_character_), NA_character_)
expect_identical(base64_urlencode(character(0)), character(0))
expect_identical(base64_urldecode(character(0)), character(0))
expect_error(base64_urlencode(NA), "character vector")
expect_error(base64_urldecode(NA), "character vector")
})
base64url/src/ 0000755 0001762 0000144 00000000000 13276254703 012661 5 ustar ligges users base64url/src/base64.c 0000644 0001762 0000144 00000014533 13276254703 014117 0 ustar ligges users /* Original source code taken from
* https://svn.apache.org/repos/asf/apr/apr/trunk/encoding/apr_base64.c
*
* Changes by Michel Lang :
* - Replaced char 62 ('+') with '-'
* - Replaced char 63 ('/') with '_'
* - Removed padding with '=' at the end of the string
* - Changed return type to void for Base64decode and Base64encode
* - Added wrappers for R
*
*/
/*
* base64.c: base64 encoding and decoding functions
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
#include
#include
#include
static const unsigned char pr2six[256] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 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, 64, 64, 64, 64, 63,
64, 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, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
static int Base64decode_len(const char *bufcoded) {
int nbytesdecoded;
register const unsigned char *bufin;
register int nprbytes;
bufin = (const unsigned char *) bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
return nbytesdecoded + 1;
}
static int Base64encode_len(int len) {
return ((len + 2) / 3 * 4) + 1;
}
static void Base64decode(char *bufplain, const char *bufcoded) {
register const unsigned char *bufin;
register unsigned char *bufout;
register int nprbytes;
bufin = (const unsigned char *) bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
bufout = (unsigned char *) bufplain;
bufin = (const unsigned char *) bufcoded;
while (nprbytes > 4) {
*(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
*(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
*(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
bufin += 4;
nprbytes -= 4;
}
if (nprbytes > 1)
*(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
if (nprbytes > 2)
*(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
if (nprbytes > 3)
*(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
*(bufout++) = '\0';
}
static void Base64encode(char *encoded, const char *string, int len) {
int i;
char *p = encoded;
for (i = 0; i < len - 2; i += 3) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1)) {
*p++ = basis_64[((string[i] & 0x3) << 4)];
} else {
*p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
}
*p++ = '\0';
}
SEXP b64e(SEXP strings) {
if (!isString(strings))
error("Argument must be a character vector");
const R_xlen_t n = xlength(strings);
SEXP result = PROTECT(allocVector(STRSXP, n));
for (R_xlen_t i = 0; i < n; i++) {
if (STRING_ELT(strings, i) == NA_STRING) {
SET_STRING_ELT(result, i, NA_STRING);
} else {
const char *plain = translateCharUTF8(STRING_ELT(strings, i));
char *encoded = malloc(sizeof(char) * Base64encode_len(strlen(plain)));
Base64encode(encoded, plain, strlen(plain));
SET_STRING_ELT(result, i, mkCharCE(encoded, CE_ANY));
free(encoded);
}
}
UNPROTECT(1);
return result;
}
SEXP b64d(SEXP strings) {
if (!isString(strings))
error("Argument must be a character vector");
const R_xlen_t n = xlength(strings);
SEXP result = PROTECT(allocVector(STRSXP, n));
for (R_xlen_t i = 0; i < n; i++) {
if (STRING_ELT(strings, i) == NA_STRING) {
SET_STRING_ELT(result, i, NA_STRING);
} else {
const char *encoded = translateCharUTF8(STRING_ELT(strings, i));
char *plain = malloc(sizeof(char) * Base64decode_len(encoded));
Base64decode(plain, encoded);
SET_STRING_ELT(result, i, mkCharCE(plain, CE_UTF8));
free(plain);
}
}
UNPROTECT(1);
return result;
}
base64url/src/init.c 0000644 0001762 0000144 00000001057 13276254703 013773 0 ustar ligges users #include
#include
#include // for NULL
#include
/* .Call calls */
extern SEXP b32d(SEXP);
extern SEXP b32e(SEXP);
extern SEXP b64d(SEXP);
extern SEXP b64e(SEXP);
static const R_CallMethodDef CallEntries[] = {
{"b32d", (DL_FUNC) &b32d, 1},
{"b32e", (DL_FUNC) &b32e, 1},
{"b64d", (DL_FUNC) &b64d, 1},
{"b64e", (DL_FUNC) &b64e, 1},
{NULL, NULL, 0}
};
void R_init_base64url(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
}
base64url/src/base32.c 0000644 0001762 0000144 00000026063 13276254703 014113 0 ustar ligges users /* base32.c -- Encode binary data using printable characters.
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006, 2010 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Adapted from base64.{h,c} by Ondřej Surý. base64.{h,c} was written
* by Simon Josefsson. Partially adapted from GNU MailUtils
* (mailbox/filter_trans.c, as of 2004-11-28). Improved by review
* from Paul Eggert, Bruno Haible, and Stepan Kasal.
*
* Interface for R package by Michel Lang.
*/
#include
#include
#include
#include
#include
static inline unsigned char to_uchar(char ch) { return ch; }
static const char b32str[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
void base32_encode(const char *in, size_t inlen, char *out) {
while (inlen) {
*out++ = b32str[(to_uchar(in[0]) >> 3) & 0x1f];
*out++ = b32str[((to_uchar(in[0]) << 2) + (--inlen ? to_uchar(in[1]) >> 6 : 0)) & 0x1f];
*out++ = (inlen ? b32str[(to_uchar(in[1]) >> 1) & 0x1f] : '=');
*out++ = (inlen ? b32str[((to_uchar(in[1]) << 4) + (--inlen ? to_uchar(in[2]) >> 4 : 0)) & 0x1f] : '=');
*out++ = (inlen ? b32str[((to_uchar(in[2]) << 1) + (--inlen ? to_uchar(in[3]) >> 7 : 0)) & 0x1f] : '=');
*out++ = (inlen ? b32str[(to_uchar(in[3]) >> 2) & 0x1f] : '=');
*out++ = (inlen ? b32str[((to_uchar(in[3]) << 3) + (--inlen ? to_uchar(in[4]) >> 5 : 0)) & 0x1f] : '=');
*out++ = inlen ? b32str[to_uchar(in[4]) & 0x1f] : '=';
if (inlen) inlen--;
if (inlen) in += 5;
}
*out++ = '\0';
}
#define B32(_) \
((_) == 'A' ? 0 \
: (_) == 'B' ? 1 \
: (_) == 'C' ? 2 \
: (_) == 'D' ? 3 \
: (_) == 'E' ? 4 \
: (_) == 'F' ? 5 \
: (_) == 'G' ? 6 \
: (_) == 'H' ? 7 \
: (_) == 'I' ? 8 \
: (_) == 'J' ? 9 \
: (_) == 'K' ? 10 \
: (_) == 'L' ? 11 \
: (_) == 'M' ? 12 \
: (_) == 'N' ? 13 \
: (_) == 'O' ? 14 \
: (_) == 'P' ? 15 \
: (_) == 'Q' ? 16 \
: (_) == 'R' ? 17 \
: (_) == 'S' ? 18 \
: (_) == 'T' ? 19 \
: (_) == 'U' ? 20 \
: (_) == 'V' ? 21 \
: (_) == 'W' ? 22 \
: (_) == 'X' ? 23 \
: (_) == 'Y' ? 24 \
: (_) == 'Z' ? 25 \
: (_) == '2' ? 26 \
: (_) == '3' ? 27 \
: (_) == '4' ? 28 \
: (_) == '5' ? 29 \
: (_) == '6' ? 30 \
: (_) == '7' ? 31 \
: -1)
static const signed char b32[0x100] = {
B32 (0), B32 (1), B32 (2), B32 (3),
B32 (4), B32 (5), B32 (6), B32 (7),
B32 (8), B32 (9), B32 (10), B32 (11),
B32 (12), B32 (13), B32 (14), B32 (15),
B32 (16), B32 (17), B32 (18), B32 (19),
B32 (20), B32 (21), B32 (22), B32 (23),
B32 (24), B32 (25), B32 (26), B32 (27),
B32 (28), B32 (29), B32 (30), B32 (31),
B32 (32), B32 (33), B32 (34), B32 (35),
B32 (36), B32 (37), B32 (38), B32 (39),
B32 (40), B32 (41), B32 (42), B32 (43),
B32 (44), B32 (45), B32 (46), B32 (47),
B32 (48), B32 (49), B32 (50), B32 (51),
B32 (52), B32 (53), B32 (54), B32 (55),
B32 (56), B32 (57), B32 (58), B32 (59),
B32 (60), B32 (61), B32 (62), B32 (63),
B32 (64), B32 (65), B32 (66), B32 (67),
B32 (68), B32 (69), B32 (70), B32 (71),
B32 (72), B32 (73), B32 (74), B32 (75),
B32 (76), B32 (77), B32 (78), B32 (79),
B32 (80), B32 (81), B32 (82), B32 (83),
B32 (84), B32 (85), B32 (86), B32 (87),
B32 (88), B32 (89), B32 (90), B32 (91),
B32 (92), B32 (93), B32 (94), B32 (95),
B32 (96), B32 (97), B32 (98), B32 (99),
B32 (100), B32 (101), B32 (102), B32 (103),
B32 (104), B32 (105), B32 (106), B32 (107),
B32 (108), B32 (109), B32 (110), B32 (111),
B32 (112), B32 (113), B32 (114), B32 (115),
B32 (116), B32 (117), B32 (118), B32 (119),
B32 (120), B32 (121), B32 (122), B32 (123),
B32 (124), B32 (125), B32 (126), B32 (127),
B32 (128), B32 (129), B32 (130), B32 (131),
B32 (132), B32 (133), B32 (134), B32 (135),
B32 (136), B32 (137), B32 (138), B32 (139),
B32 (140), B32 (141), B32 (142), B32 (143),
B32 (144), B32 (145), B32 (146), B32 (147),
B32 (148), B32 (149), B32 (150), B32 (151),
B32 (152), B32 (153), B32 (154), B32 (155),
B32 (156), B32 (157), B32 (158), B32 (159),
B32 (160), B32 (161), B32 (162), B32 (163),
B32 (164), B32 (165), B32 (166), B32 (167),
B32 (168), B32 (169), B32 (170), B32 (171),
B32 (172), B32 (173), B32 (174), B32 (175),
B32 (176), B32 (177), B32 (178), B32 (179),
B32 (180), B32 (181), B32 (182), B32 (183),
B32 (184), B32 (185), B32 (186), B32 (187),
B32 (188), B32 (189), B32 (190), B32 (191),
B32 (192), B32 (193), B32 (194), B32 (195),
B32 (196), B32 (197), B32 (198), B32 (199),
B32 (200), B32 (201), B32 (202), B32 (203),
B32 (204), B32 (205), B32 (206), B32 (207),
B32 (208), B32 (209), B32 (210), B32 (211),
B32 (212), B32 (213), B32 (214), B32 (215),
B32 (216), B32 (217), B32 (218), B32 (219),
B32 (220), B32 (221), B32 (222), B32 (223),
B32 (224), B32 (225), B32 (226), B32 (227),
B32 (228), B32 (229), B32 (230), B32 (231),
B32 (232), B32 (233), B32 (234), B32 (235),
B32 (236), B32 (237), B32 (238), B32 (239),
B32 (240), B32 (241), B32 (242), B32 (243),
B32 (244), B32 (245), B32 (246), B32 (247),
B32 (248), B32 (249), B32 (250), B32 (251),
B32 (252), B32 (253), B32 (254), B32 (255)
};
#if UCHAR_MAX == 255
#define uchar_in_range(c) true
#else
#define uchar_in_range(c) ((c) <= 255)
#endif
static bool isbase32(char ch) {
return uchar_in_range(to_uchar(ch)) && 0 <= b32[to_uchar(ch)];
}
static bool base32_decode(const char *in, size_t inlen, char *out, size_t *outlen) {
size_t outleft = *outlen;
while (inlen >= 2) {
if (!isbase32(in[0]) || !isbase32(in[1]))
break;
if (outleft) {
*out++ = ((b32[to_uchar(in[0])] << 3) | (b32[to_uchar(in[1])] >> 2));
outleft--;
}
if (inlen == 2)
break;
if (in[2] == '=') {
if (inlen != 8)
break;
if ((in[3] != '=') || (in[4] != '=') || (in[5] != '=') || (in[6] != '=') || (in[7] != '='))
break;
} else {
if (!isbase32(in[2]) || !isbase32(in[3]))
break;
if (outleft) {
*out++ = ((b32[to_uchar(in[1])] << 6) | ((b32[to_uchar(in[2])] << 1) & 0x3E) | (b32[to_uchar(in[3])] >> 4));
outleft--;
}
if (inlen == 4)
break;
if (in[4] == '=') {
if (inlen != 8)
break;
if ((in[5] != '=') || (in[6] != '=') || (in[7] != '='))
break;
} else {
if (!isbase32 (in[3]) || !isbase32(in[4]))
break;
if (outleft) {
*out++ = ((b32[to_uchar(in[3])] << 4) | (b32[to_uchar(in[4])] >> 1));
outleft--;
}
if (inlen == 5)
break;
if (in[5] == '=') {
if (inlen != 8)
break;
if ((in[6] != '=') || (in[7] != '='))
break;
} else {
if (!isbase32 (in[5]) || !isbase32 (in[6]))
break;
if (outleft) {
*out++ = ((b32[to_uchar(in[4])] << 7) | (b32[to_uchar(in[5])] << 2) | (b32[to_uchar(in[6])] >> 3));
outleft--;
}
if (inlen == 7)
break;
if (in[7] == '=') {
if (inlen != 8)
break;
} else {
if (!isbase32 (in[7]))
break;
if (outleft) {
*out++ = ((b32[to_uchar(in[6])] << 5) | (b32[ to_uchar(in[7])]));
outleft--;
}
}
}
}
}
in += 8;
inlen -= 8;
}
*out++ = '\0';
return (inlen == 0);
}
SEXP b32e(SEXP strings) {
if (!isString(strings))
error("Argument must be a character vector");
const R_xlen_t n = xlength(strings);
SEXP result = PROTECT(allocVector(STRSXP, n));
for (R_xlen_t i = 0; i < n; i++) {
if (STRING_ELT(strings, i) == NA_STRING) {
SET_STRING_ELT(result, i, NA_STRING);
} else {
const char *plain = translateCharUTF8(STRING_ELT(strings, i));
R_len_t n_in = strlen(plain);
R_len_t n_out = 1 + ((n_in + 4) / 5) * 8;
if (n_in > n_out) {
UNPROTECT(1);
error("Input is too long");
}
char *encoded = malloc(n_out);
if (encoded == NULL) {
free(encoded);
UNPROTECT(1);
error("Failed to allocate memory");
}
base32_encode(plain, n_in, encoded);
SET_STRING_ELT(result, i, mkCharCE(encoded, CE_ANY));
free(encoded);
}
}
UNPROTECT(1);
return result;
}
SEXP b32d(SEXP strings) {
if (!isString(strings))
error("Argument must be a character vector");
const R_xlen_t n = xlength(strings);
SEXP result = PROTECT(allocVector(STRSXP, n));
for (R_xlen_t i = 0; i < n; i++) {
if (STRING_ELT(strings, i) == NA_STRING) {
SET_STRING_ELT(result, i, NA_STRING);
} else {
const char *encoded = translateCharUTF8(STRING_ELT(strings, i));
R_len_t n_in = strlen(encoded);
if (n_in == 0) {
SET_STRING_ELT(result, i, mkChar(""));
} else {
size_t n_out = 5 * (n_in / 8) + 4;
char *plain = malloc(n_out);
if (plain == NULL) {
free(plain);
UNPROTECT(1);
error("Failed to allocate memory");
}
if (!base32_decode(encoded, n_in, plain, &n_out) || (n_out == 0 && n_in > 0)) {
free(plain);
UNPROTECT(1);
error("Error decoding string from base32");
}
SET_STRING_ELT(result, i, mkCharCE(plain, CE_UTF8));
free(plain);
}
}
}
UNPROTECT(1);
return result;
}
base64url/NAMESPACE 0000644 0001762 0000144 00000000364 13107542550 013305 0 ustar ligges users # Generated by roxygen2: do not edit by hand
export(base32_decode)
export(base32_encode)
export(base64_urldecode)
export(base64_urlencode)
useDynLib(base64url,b32d)
useDynLib(base64url,b32e)
useDynLib(base64url,b64d)
useDynLib(base64url,b64e)
base64url/NEWS.md 0000644 0001762 0000144 00000001017 13274542374 013171 0 ustar ligges users # base64url 1.4
* Disabled tests which compared encodings of non-ascii strings to encodings in
packages `base64enc` and `openssl` on some systems.
# base64url 1.3
* Fixed decoding on windows for input encoded in native encoding.
# base64url 1.2
* Native routines are now registered.
* Vignette builds without `microbenchmark` installed.
* Update to new backports.
# base64url 1.1
* Added `base32_encode()` and `base32_decode()`.
* Changed license to GPL-3.
* Fixed vignette title.
# base64url 1.0
* Initial release.
base64url/R/ 0000755 0001762 0000144 00000000000 13274540254 012270 5 ustar ligges users base64url/R/base32.R 0000644 0001762 0000144 00000002607 13274540254 013477 0 ustar ligges users #' @title Encode to base32 or Decode from base32
#'
#' @description
#' Simple RFC4648 base32 encoder/decoder. Pads with \dQuote{=}.
#'
#' @param x [\code{character(1)}]\cr
#' Character vector to encode or decode.
#' @param use.padding [\code{logical(1)}]\cr
#' If \code{TRUE}, \code{base32_encode} returns a string whose length is a multiple of 8,
#' padded with trailing \dQuote{=} if required.
#' \code{base32_decode} expects such a string unless this is set to \code{FALSE} (default).
#' The internal algorithm currently works with padding, thus it is faster to set this to \code{TRUE}.
#' @return [\code{character}] of the same length as input \code{x}.
#' @references Implementation based on base32 encoder/decoder in the GNU lib: \url{https://www.gnu.org/software/gnulib/}.
#' @useDynLib base64url b32e
#' @export
#' @examples
#' x = "plain text"
#' encoded = base32_encode(x)
#' decoded = base32_decode(encoded)
#' print(encoded)
#' print(decoded)
base32_encode = function(x, use.padding = FALSE) {
res = .Call(b32e, enc2utf8(x))
if (isTRUE(use.padding))
return(res)
sub("=+$", "", res)
}
#' @rdname base32_encode
#' @useDynLib base64url b32d
#' @export
base32_decode = function(x, use.padding = FALSE) {
if (!isTRUE(use.padding)) {
i = which(!is.na(x) & nzchar(x))
if (length(i))
x[i] = paste0(x[i], strrep("=", 7L - ((nchar(x[i]) - 1L) %% 8L)))
}
.Call(b32d, x)
}
base64url/R/base64.R 0000644 0001762 0000144 00000002165 13250515635 013502 0 ustar ligges users #' @title Encode to base64 or Decode from base64
#'
#' @description
#' In contrast to RFC3548, the 62nd character (\sQuote{+}) is replaced with \sQuote{-}, the 63rd character (\sQuote{/}) is replaced with \sQuote{_}.
#' Furthermore, the encoder does not fill the string with trailing \sQuote{=}.
#' The resulting encoded strings comply to the regular expression pattern \dQuote{[A-Za-z0-9_-]} and thus are safe to use in URLs
#' or for file names.
#'
#' @param x [\code{character(1)}]\cr
#' Character vector to encode or decode.
#'
#' @return [\code{character}] of the same length as input \code{x}.
#' @references Implementation based on base64 encoder/decoder in the Apache Portable Runtime (APR): \url{https://svn.apache.org/repos/asf/apr/apr/trunk/encoding/apr_base64.c}
#' @useDynLib base64url b64e
#' @export
#' @examples
#' x = "plain text"
#' encoded = base64_urlencode(x)
#' decoded = base64_urldecode(encoded)
#' print(encoded)
#' print(decoded)
base64_urlencode = function(x) {
.Call(b64e, enc2utf8(x))
}
#' @rdname base64_urlencode
#' @useDynLib base64url b64d
#' @export
base64_urldecode = function(x) {
.Call(b64d, x)
}
base64url/R/zzz.R 0000644 0001762 0000144 00000000120 13250451706 013236 0 ustar ligges users .onLoad = function(libname, pkgname) {
backports::import(pkgname, "strrep")
}
base64url/vignettes/ 0000755 0001762 0000144 00000000000 13276254703 014102 5 ustar ligges users base64url/vignettes/Benchmarks.Rmd 0000644 0001762 0000144 00000005103 13250515635 016616 0 ustar ligges users ---
title: "Benchmark"
author: "Michel Lang"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Benchmark}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r,include=FALSE,cache=FALSE}
do.eval = requireNamespace("microbenchmark", quietly = TRUE)
```
This small benchmark compares the performance of the base64 encoding/decoding in package `base64url` with the implementations in the packages [`base64enc`](https://cran.r-project.org/package=base64enc) and [`openssl`](https://cran.r-project.org/package=openssl).
## Encoding of a single string
```{r, eval=do.eval}
library(base64url)
library(base64enc)
library(openssl)
library(microbenchmark)
x = "plain text"
microbenchmark(
base64url = base64_urlencode(x),
base64enc = base64encode(charToRaw(x)),
openssl = base64_encode(x)
)
```
## Decoding of a single string
```{r, eval = do.eval}
x = "N0JBLlRaUTp1bi5KOW4xWStNWEJoLHRQaDZ3"
microbenchmark(
base64url = base64_urldecode(x),
base64enc = rawToChar(base64decode(x)),
openssl = rawToChar(base64_decode(x))
)
```
## Encoding and decoding of character vectors
Here, the task has changed from encoding/decoding a single string to processing multiple strings stored inside a character vector.
First, we create a small utility function which returns `n` random strings with a random number of characters (between 1 and 32) each.
```{r, eval = do.eval}
rand = function(n, min = 1, max = 32) {
chars = c(letters, LETTERS, as.character(0:9), c(".", ":", ",", "+", "-", "*", "/"))
replicate(n, paste0(sample(chars, sample(min:max, 1), replace = TRUE), collapse = ""))
}
set.seed(1)
rand(10)
```
Only `base64url` is vectorized for string input, the alternative implementations need wrappers to process character vectors:
```{r, eval = do.eval}
base64enc_encode = function(x) {
vapply(x, function(x) base64encode(charToRaw(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_encode = function(x) {
vapply(x, function(x) base64_encode(x), NA_character_, USE.NAMES = FALSE)
}
base64enc_decode = function(x) {
vapply(x, function(x) rawToChar(base64decode(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_decode = function(x) {
vapply(x, function(x) rawToChar(base64_decode(x)), NA_character_, USE.NAMES = FALSE)
}
```
The following benchmark measures the runtime to encode 1000 random strings and then decode them again:
```{r, eval = do.eval}
set.seed(1)
x = rand(1000)
microbenchmark(
base64url = base64_urldecode(base64_urlencode(x)),
base64enc = base64enc_decode(base64enc_encode(x)),
openssl = openssl_decode(openssl_encode(x))
)
```
base64url/README.md 0000644 0001762 0000144 00000002711 13050560115 013335 0 ustar ligges users # base64url
[](https://cran.r-project.org/package=base64url)
[](https://travis-ci.org/mllg/base64url)
[](https://ci.appveyor.com/project/mllg/base64url/branch/master)
[](https://coveralls.io/github/mllg/base64url?branch=master)
In contrast to base64 RFC3548, the 62nd character (`'+'`) is replaced with `'-'`, the 63rd character (`'/'`) is replaced with `'_'`.
Furthermore, the encoder does not fill the string with trailing `'='`.
The resulting encoded strings comply to the regular expression pattern `'[A-Za-z0-9_-]'` and thus are safe to use in URLs or for file names.
For a small benchmark, see the [vignette](https://cran.r-project.org/package=base64url/vignettes/Benchmarks.html).
As of version 1.1, this package also ships with a simple base32 encoder/decoder suited to mangle file names on case insensitive file systems.
## Installation
For the stable release, just install the latest version from [CRAN](https://cran.r-project.org/package=base64url):
```{R}
install.packages("base64url")
```
For the development version, use [devtools](https://cran.r-project.org/package=devtools):
```{R}
devtools::install_github("mllg/base64url")
```
base64url/MD5 0000644 0001762 0000144 00000002070 13276256704 012404 0 ustar ligges users e355c9b8a74fab1f617fce3a9bec3a15 *DESCRIPTION
335b7504e8adcce63098535682e25a70 *NAMESPACE
b147fa3663f670544c1fc96629d28c35 *NEWS.md
a77070d468abfe4b9fb0a5b06e808b68 *R/base32.R
70f61389e5460a5ed43bf3518f94e698 *R/base64.R
fd5a1b9c4c9d8dd8341730b115e2e223 *R/zzz.R
16598200d896ab87200bdd82659cce2e *README.md
d1923a9bbcf5e350a05ec142b87b4888 *build/vignette.rds
398ae3d85788dd220714ce1a4040ecad *inst/doc/Benchmarks.R
1cf1683e35aed4221cbe354532f237a2 *inst/doc/Benchmarks.Rmd
a8df367d1d980742b08565e1802a8bf1 *inst/doc/Benchmarks.html
e2e6da0556cca19b1dc57b7d399fe5b1 *man/base32_encode.Rd
af0c6709af82452c6aa3198e3173060d *man/base64_urlencode.Rd
22a9d873171d8bff0b74008e6c48dbc9 *src/base32.c
524e0e81ff1053c24afbc59bb303f0a7 *src/base64.c
12187d1e3b809360057f7f46bfc5332b *src/init.c
c62047c9d0508b07ad001a6c12e60507 *tests/testthat.R
019194c2e00257695eca1a1deabd8176 *tests/testthat/helper.R
46fd84e71926e7f95bcaa6a27b0bfbb0 *tests/testthat/test_base32.R
8c1f82519156b8043a73b8608b69f3cb *tests/testthat/test_base64.R
1cf1683e35aed4221cbe354532f237a2 *vignettes/Benchmarks.Rmd
base64url/build/ 0000755 0001762 0000144 00000000000 13276254703 013171 5 ustar ligges users base64url/build/vignette.rds 0000644 0001762 0000144 00000000306 13276254703 015527 0 ustar ligges users b```b`f@&0`b fd`a|NyEzA)hpY4 ~$m%9h<ȦA Zּb4]RRR@g;<E
T
[fN*ސ89
dBw(,/׃
@?{49'ݣ\)%ziE@ w base64url/DESCRIPTION 0000644 0001762 0000144 00000002700 13276256704 013602 0 ustar ligges users Package: base64url
Type: Package
Title: Fast and URL-Safe Base64 Encoder and Decoder
Version: 1.4
Authors@R: c(
person("Michel", "Lang", NULL, "michellang@gmail.com",
role = c("cre", "aut"), comment = c(ORCID = "0000-0001-9754-0393")),
person(NULL, "Apache Foundation", NULL, NULL, role = c("ctb", "cph")),
person(NULL, "Free Software Foundation", NULL, NULL, role = c("ctb", "cph"))
)
Description: In contrast to RFC3548, the 62nd character ("+") is replaced with
"-", the 63rd character ("/") is replaced with "_". Furthermore, the encoder
does not fill the string with trailing "=". The resulting encoded strings
comply to the regular expression pattern "[A-Za-z0-9_-]" and thus are
safe to use in URLs or for file names.
The package also comes with a simple base32 encoder/decoder suited for
case insensitive file systems.
URL: https://github.com/mllg/base64url
BugReports: https://github.com/mllg/base64url/issues
NeedsCompilation: yes
License: GPL-3
Encoding: UTF-8
Imports: backports (>= 1.1.0)
Suggests: base64enc, checkmate, knitr, microbenchmark, openssl,
rmarkdown, testthat
RoxygenNote: 6.0.1
VignetteBuilder: knitr
Packaged: 2018-05-14 09:41:23 UTC; lang
Author: Michel Lang [cre, aut] (),
Apache Foundation [ctb, cph],
Free Software Foundation [ctb, cph]
Maintainer: Michel Lang
Repository: CRAN
Date/Publication: 2018-05-14 09:58:28 UTC
base64url/man/ 0000755 0001762 0000144 00000000000 13050560115 012630 5 ustar ligges users base64url/man/base64_urlencode.Rd 0000644 0001762 0000144 00000002112 13050560115 016237 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/base64.R
\name{base64_urlencode}
\alias{base64_urlencode}
\alias{base64_urldecode}
\title{Encode to base64 or Decode from base64}
\usage{
base64_urlencode(x)
base64_urldecode(x)
}
\arguments{
\item{x}{[\code{character(1)}]\cr
Character vector to encode or decode.}
}
\value{
[\code{character}] of the same length as input \code{x}.
}
\description{
In contrast to RFC3548, the 62nd character (\sQuote{+}) is replaced with \sQuote{-}, the 63rd character (\sQuote{/}) is replaced with \sQuote{_}.
Furthermore, the encoder does not fill the string with trailing \sQuote{=}.
The resulting encoded strings comply to the regular expression pattern \dQuote{[A-Za-z0-9_-]} and thus are safe to use in URLs
or for file names.
}
\examples{
x = "plain text"
encoded = base64_urlencode(x)
decoded = base64_urldecode(encoded)
print(encoded)
print(decoded)
}
\references{
Implementation based on base64 encoder/decoder in the Apache Portable Runtime (APR): \url{https://svn.apache.org/repos/asf/apr/apr/trunk/encoding/apr_base64.c}
}
base64url/man/base32_encode.Rd 0000644 0001762 0000144 00000002143 13050560115 015513 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/base32.R
\name{base32_encode}
\alias{base32_encode}
\alias{base32_decode}
\title{Encode to base32 or Decode from base32}
\usage{
base32_encode(x, use.padding = FALSE)
base32_decode(x, use.padding = FALSE)
}
\arguments{
\item{x}{[\code{character(1)}]\cr
Character vector to encode or decode.}
\item{use.padding}{[\code{logical(1)}]\cr
If \code{TRUE}, \code{base32_encode} returns a string whose length is a multiple of 8,
padded with trailing \dQuote{=} if required.
\code{base32_decode} expects such a string unless this is set to \code{FALSE} (default).
The internal algorithm currently works with padding, thus it is faster to set this to \code{TRUE}.}
}
\value{
[\code{character}] of the same length as input \code{x}.
}
\description{
Simple RFC4648 base32 encoder/decoder. Pads with \dQuote{=}.
}
\examples{
x = "plain text"
encoded = base32_encode(x)
decoded = base32_decode(encoded)
print(encoded)
print(decoded)
}
\references{
Implementation based on base32 encoder/decoder in the GNU lib: \url{https://www.gnu.org/software/gnulib/}.
}