The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

b64

R-CMD-check

The goal of b64 is to provide a very fast, lightweight, and vectorized base64 encoder and decoder.

Installation

You can install the development version of b64 like so:

pak::pak("extendr/b64")

Example

Encode to base64 using encode().

library(b64)

hello <- encode("Hello, from extendr")
hello
#> [1] "SGVsbG8sIGZyb20gZXh0ZW5kcg=="

Decode using decode()

decoded <- decode(hello)
decoded
#> <blob[1]>
#> [1] blob[19 B]

We can convert the decoded base64 to characters and see how it worked.

rawToChar(decoded[[1]])
#> [1] "Hello, from extendr"

Vectorized

Both encode() and decode() are vectorized.

lorem <- unlist(lorem::ipsum(5, 1,  5))
lorem
#> [1] "Sit ligula senectus litora viverra consequat."          
#> [2] "Consectetur vulputate vivamus sapien a ridiculus porta."
#> [3] "Ipsum orci cras posuere lacus."                         
#> [4] "Lorem nostra hendrerit nascetur vel duis consequat."    
#> [5] "Adipiscing dui blandit vestibulum bibendum?"

encoded <- encode(lorem)
encoded
#> [1] "U2l0IGxpZ3VsYSBzZW5lY3R1cyBsaXRvcmEgdml2ZXJyYSBjb25zZXF1YXQu"                
#> [2] "Q29uc2VjdGV0dXIgdnVscHV0YXRlIHZpdmFtdXMgc2FwaWVuIGEgcmlkaWN1bHVzIHBvcnRhLg=="
#> [3] "SXBzdW0gb3JjaSBjcmFzIHBvc3VlcmUgbGFjdXMu"                                    
#> [4] "TG9yZW0gbm9zdHJhIGhlbmRyZXJpdCBuYXNjZXR1ciB2ZWwgZHVpcyBjb25zZXF1YXQu"        
#> [5] "QWRpcGlzY2luZyBkdWkgYmxhbmRpdCB2ZXN0aWJ1bHVtIGJpYmVuZHVtPw=="

We can decode all of these using decode() as well. This will always return a blob object.

decode(encoded)
#> <blob[5]>
#> [1] blob[45 B] blob[55 B] blob[30 B] blob[51 B] blob[43 B]

Encoding and decoding files

b64 shines when encoding and decoding files. encode_file() and decode_file() both work by reading a file as a stream making it far faster than the alternative.

tmp <- tempfile() 
fp <- "https://github.com/datablist/sample-csv-files/raw/main/files/leads/leads-100000.csv"

download.file(fp, tmp)

bench::mark(
  b64 = encode_file(tmp),
  base64enc = base64enc::base64encode(tmp)
)
#> Warning: Some expressions had a GC in every iteration; so filtering is
#> disabled.
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 b64          39.8ms   41.3ms     24.0       24MB      0  
#> 2 base64enc   112.1ms  115.2ms      8.56    66.5MB     17.1

While the encoding is very impressive, better yet is the decoding performance.

# create a temp file
tmp2 <- tempfile()

# encode it and write to tmep file
encode_file(tmp) |>
  charToRaw() |>
  writeBin(tmp2)

bench::mark(
  b64 = decode_file(tmp2),
  base64enc = base64enc::base64decode(file(tmp2))
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 b64          16.1ms   16.8ms     56.1       18MB     9.34
#> 2 base64enc   209.1ms  210.7ms      4.75      18MB     0

Alternative engines

Out of the box, b64 provides a number of pre-configured engines that can be used. The function engine() allows you to choose one of these different engines For example, engine("url_safe") provides a standard engine that uses a url-safe alphabet with padding.

url_engine <- engine("url_safe")
url_safe_encoded <- encode("\xfa\xec U", url_engine)
url_safe_encoded
#> [1] "-uwgVQ=="

If we try to decode this using the standard engine, we will encounter an error.

decode(url_safe_encoded)
#> Error in decode_(what, eng): Invalid byte 45, offset 0.

We can use our new engine to decode it.

decode(url_safe_encoded, url_engine)
#> <blob[1]>
#> [1] blob[4 B]

Custom Engines

We can create custom engines with new_engine(). This allows us to provide our on alphabet and configuration.

We can use one of the many predefined alphabets or create one our selves with new_alphabet(). We can also specify our engine config using new_config() which lets us choose whether or not to pad and how to handle decoding.

my_eng <- new_engine(
  alphabet("crypt"),
  new_config(TRUE, TRUE, "none")
)

This engine can be used to encode or decode text.

txt <- "lorem ipsum sit dolor amet"

encode(txt, my_eng)
#> [1] "P4xmNKoUOL/nRKoUQqZo64FjP4xm643hNLE="

Compare this to the standard encoder:

encode(txt)
#> [1] "bG9yZW0gaXBzdW0gc2l0IGRvbG9yIGFtZXQ="

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.