Skip to content

Commit

Permalink
fix: encode timestamps correctly in cpp implementation (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Mar 1, 2023
1 parent 404487d commit c7fedc3
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 19 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

Create and transform ULIDs

This library will use the CPP implementation from https://github.com/suyash/ulid if cython is available, and will fallback to pure python if it is not.

## Example

```python
Expand Down
69 changes: 68 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ python = "^3.10"
[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
pytest-cov = "^3.0"
Cython = "^0.29.32"
setuptools = "^65.4.1"

[tool.semantic_release]
branch = "main"
Expand Down
2 changes: 2 additions & 0 deletions src/ulid_transform/_ulid_impl.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ def _ulid_at_time(time: float) -> str:
return _cpp_ulid_at_time(time).decode("ascii")

def _ulid_to_bytes(ulid_str: str) -> bytes:
if len(ulid_str) != 26:
raise ValueError("ULID must be 26 characters")
return _cpp_ulid_to_bytes(ulid_str.encode("ascii"))
4 changes: 2 additions & 2 deletions src/ulid_transform/ulid_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# From https://github.com/ahawker/ulid/blob/06289583e9de4286b4d80b4ad000d137816502ca/ulid/base32.py#L102
#: Array that maps encoded string char byte values to enable O(1) lookups.
DECODE = array.array(
_DECODE = array.array(
"B",
(
0xFF,
Expand Down Expand Up @@ -347,7 +347,7 @@ def ulid_to_bytes(value: str) -> bytes:
if len(value) != 26:
raise ValueError("ULID must be 26 characters")
encoded = value.encode("ascii")
decoding = DECODE
decoding = _DECODE
return bytes(
(
((decoding[encoded[0]] << 5) | decoding[encoded[1]]) & 0xFF,
Expand Down
30 changes: 14 additions & 16 deletions src/ulid_transform/ulid_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
#include "ulid.hh"
#include "ulid_wrapper.h"
#include <chrono>
#include "ulid.hh"

using namespace std;


std::string _cpp_ulid() {
ulid::ULID ulid;
ulid::EncodeNowRand(ulid);
return ulid::Marshal(ulid);
ulid::ULID ulid;
ulid::EncodeNowRand(ulid);
return ulid::Marshal(ulid);
}

std::string _cpp_ulid_at_time(double timestamp) {
const auto encoded_time = chrono::system_clock::to_time_t(chrono::system_clock::time_point(chrono::duration_cast<chrono::seconds>(chrono::duration<double>(timestamp))));
ulid::ULID ulid;
ulid::EncodeTime(encoded_time, ulid);
ulid::EncodeEntropyRand(ulid);
return ulid::Marshal(ulid);
std::string _cpp_ulid_at_time(double epoch_time) {
time_t encoded_time = static_cast<time_t>(epoch_time*1000);
ulid::ULID ulid;
ulid::EncodeTime(encoded_time, ulid);
ulid::EncodeEntropyRand(ulid);
return ulid::Marshal(ulid);
}

std::string _cpp_ulid_to_bytes(std::string ulid_string) {
ulid::ULID ulid = ulid::Unmarshal(ulid_string.c_str());
std::vector<uint8_t> data = ulid::MarshalBinary(ulid);
std::string str(reinterpret_cast<char*>(data.data()), data.size());
return str;
ulid::ULID ulid = ulid::Unmarshal(ulid_string.c_str());
std::vector<uint8_t> data = ulid::MarshalBinary(ulid);
std::string str(reinterpret_cast<char *>(data.data()), data.size());
return str;
}
5 changes: 5 additions & 0 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def test_ulid_to_bytes_2():
)


def test_timestamp_string():
ulid = ulid_at_time(1677627631.2127638)
assert ulid[:10] == "01GTD6C9KC"


def test_timestamp():
now = time.time()
ulid = ulid_at_time(now)
Expand Down

0 comments on commit c7fedc3

Please sign in to comment.