Skip to content

Commit e4d0371

Browse files
authored
Reimplemented encoding and implemented decoding (#1)
- base64url support - added more tests - added performance tests - improved README.md
1 parent 302a8af commit e4d0371

File tree

9 files changed

+598
-63
lines changed

9 files changed

+598
-63
lines changed

.codecov.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
coverage:
2+
status:
3+
project:
4+
default: off
5+
base64:
6+
flags: base64
7+
target: 100%
8+
unittest:
9+
flags: unittest
10+
performance:
11+
flags: performance
12+
flags:
13+
base64:
14+
paths:
15+
- Sources/Base64
16+
performance:
17+
paths:
18+
- Sources/PerformanceTest
19+
unittests:
20+
paths:
21+
- Tests/Base64Tests

.github/workflows/ci.yaml

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88
- master
99

1010
jobs:
11+
1112
"tuxOS-Tests":
1213
runs-on: ubuntu-latest
1314
strategy:
@@ -23,8 +24,6 @@ jobs:
2324
uses: actions/checkout@v1
2425
with:
2526
fetch-depth: 1
26-
- name: Install dependencies
27-
run: apt-get update && apt-get install -y zlib1g-dev zip openssl libssl-dev
2827
- name: Test
2928
run: swift test --enable-code-coverage --enable-test-discovery
3029
- name: Convert coverage files
@@ -33,6 +32,28 @@ jobs:
3332
uses: codecov/codecov-action@v1.0.3
3433
with:
3534
token: ${{secrets.CODECOV_TOKEN}}
35+
flags: base64,unittests
36+
file: info.lcov
37+
38+
"tuxOS-Performance-Tests":
39+
runs-on: ubuntu-latest
40+
strategy:
41+
matrix:
42+
tag: ['5.1']
43+
container:
44+
image: swift:${{ matrix.tag }}
45+
volumes:
46+
- $GITHUB_WORKSPACE:/src
47+
options: --workdir /src
48+
steps:
49+
- name: Checkout
50+
uses: actions/checkout@v1
51+
with:
52+
fetch-depth: 1
53+
- name: Build
54+
run: swift build -c release
55+
- name: Run test
56+
run: .build/release/Base64PerformanceTest
3657

3758
"macOS-Tests":
3859
runs-on: macOS-latest
@@ -54,5 +75,16 @@ jobs:
5475
swift package generate-xcodeproj
5576
xcodebuild -quiet -parallel-testing-enabled YES -scheme swift-base64-Package -enableCodeCoverage YES build test
5677
- name: Codecov
57-
run: bash <(curl -s https://codecov.io/bash) -J 'Base64' -t ${{secrets.CODECOV_TOKEN}}
78+
run: bash <(curl -s https://codecov.io/bash) -t ${{secrets.CODECOV_TOKEN}} -F base64,unittests -f *.coverage.txt
5879

80+
"macOS-Performance-Tests":
81+
runs-on: macOS-latest
82+
steps:
83+
- name: Checkout
84+
uses: actions/checkout@v1
85+
with:
86+
fetch-depth: 1
87+
- name: Build
88+
run: swift build -c release
89+
- name: Run test
90+
run: .build/release/Base64PerformanceTest

Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ let package = Package(
1212
],
1313
dependencies: [],
1414
targets: [
15+
.target(
16+
name: "Base64PerformanceTest",
17+
dependencies: ["Base64"]),
1518
.target(
1619
name: "Base64",
1720
dependencies: []),

README.md

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,71 @@
66
![macOS](https://img.shields.io/badge/os-macOS-green.svg?style=flat)
77
![tuxOS](https://img.shields.io/badge/os-tuxOS-green.svg?style=flat)
88

9-
The goal of this project is to provide an easy to use base64 encode and decode algorithm
10-
without the use of the Foundation framework.
9+
The goal of this project is to provide an easy to use [RFC4648](https://tools.ietf.org/html/rfc4648)
10+
complient base64 encode and decode implentation in pure Swift. Further this implementation
11+
tries to be faster than the [Foundation Base64](https://developer.apple.com/documentation/foundation/nsdata)
12+
implementation.
13+
14+
Right now the implementation is dead simple. No fancy precomputed lookup tables, no fancy
15+
SIMD instructions.
1116

1217
Everything began with [an issue](https://github.com/apple/swift-nio/issues/1265) on [`swift-nio`](https://github.com/apple/swift-nio).
1318

19+
## Status
20+
21+
- [x] support for base64 and base64url
22+
- [x] faster than Foundation
23+
- [ ] decoding can ignore line breaks
24+
- [ ] encoding can insert line breaks
25+
- [ ] 100% test coverage
26+
27+
## Performance
28+
29+
Super [simple performance test](https://github.com/fabianfett/swift-base64/blob/master/Sources/Base64PerformanceTest/main.swift)
30+
to ensure speediness of this implementation. Encoding and decoding 1m times the base64 string:
31+
32+
```
33+
AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==
34+
```
35+
36+
#### macOS
37+
38+
MacBook Pro (15-inch, late 2016 - the first one with the butterfly keyboard).
39+
Quad Core 2,7 GHz Intel Core i7
40+
41+
| | Encoding | Decoding |
42+
|:--|:--|:--|
43+
| Foundation | 2.21s | 2.28s |
44+
| swift-base64 | 1.01s | 1.06s |
45+
| Speedup | 2.18x | 2.14x |
46+
47+
#### linux
48+
49+
Whatevar runs GitHub Actions 😉
50+
51+
| | Encoding | Decoding |
52+
|:--|:--|:--|
53+
| Foundation | 33.64s | 3.49s |
54+
| swift-base64 | 1.07s | 1.27s |
55+
| Speedup | 31.18x | 2.74x |
56+
57+
I have no idea why Foundation base64 encoding is so slow on linux. 🤷‍♂️
58+
59+
## Literature for a faster algorithm
60+
61+
I would really like to speedup this repository further to be way faster than it is today.
62+
Some food for thought of how this could be approached can be found here:
63+
64+
- [Chromium precomputed lookup tables](https://github.com/lemire/fastbase64/blob/master/src/chromiumbase64.c)
65+
- [Wojciech Muła, Daniel Lemire: Faster Base64 Encoding and Decoding using AVX2 Instructions](https://arxiv.org/pdf/1704.00605.pdf).
66+
- [Daniel Lemire's blog - Ridiculously fast base64 encoding and decoding](https://lemire.me/blog/2018/01/17/ridiculously-fast-base64-encoding-and-decoding/)
67+
- [Swift SIMD support](https://github.com/apple/swift-evolution/blob/master/proposals/0229-simd.md)
68+
69+
## Alternatives
1470

15-
### Maybe one day, we can make this really swift.
71+
As of today (2019-12-10) the author is only aware of two alternatives that both offer
72+
only encoding. Only one of those is a real library.
1673

17-
Some literature:
74+
- [SwiftyBase64](https://github.com/drichardson/SwiftyBase64)
75+
- [NIOWebSocket - Base64](https://github.com/apple/swift-nio/blob/master/Sources/NIOWebSocket/Base64.swift)
1876

19-
- [RFC4648](https://tools.ietf.org/html/rfc4648)
20-
- [Ridiculously fast base64 encoding and decoding - Daniel Lemire's blog](https://lemire.me/blog/2018/01/17/ridiculously-fast-base64-encoding-and-decoding/)

0 commit comments

Comments
 (0)