# How to implement Base58 to Bytes in Crystal?

**URL:** <https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462>\
**Category:** Help & Support\
**Created:** [March 12, 2022, 10:34am UTC](https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462 "2022-03-12T10:34:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![wout](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/wout/32/1578_2.png) [@wout](https://forum.crystal-lang.org/u/wout)\
**Post date:** [March 12, 2022, 10:34am UTC](https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462/1 "2022-03-12T10:34:28Z")

</div>

I’m trying to figure out how to verify a signature that’s generated using a Tezos crypto wallet on the client-side. From the wallet, I get the signed message and the wallet’s public key, and the message is known to me because it’s generated on the server before signing.

I found an example in JavaScript: [https://repl.it/@DalyIng/verifyTezosSignature](https://repl.it/@DalyIng/verifyTezosSignature)

I already found [GitHub - didactic-drunk/sodium.cr: Crystal wrapper for the libsodium crypto API](https://github.com/didactic-drunk/sodium.cr), but I’m struggling with base58 decoding.

The JS counterpart of the code is here: [base-x/index.js at master · cryptocoinjs/base-x · GitHub](https://github.com/cryptocoinjs/base-x/blob/master/src/index.js)

Can anyone help me on the way here? Or is my best option to port the JS variant?

---

<div class="post-metadata">

**Author:** ![anon69898395](https://avatars.discourse-cdn.com/v4/letter/a/848f3c/32.png) [@anon69898395](https://forum.crystal-lang.org/u/anon69898395)\
**Post date:** [March 14, 2022, 2:43pm UTC](https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462/2 "2022-03-14T14:43:06Z")

</div>

Don’t know what all you need, but if it’s just converting Bytes to String and vice versa, this should probably do it:

```auto
require "big"
T= "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

def encode (bytes : Bytes) : String
  r= Array(Char).new
  big= bytes.reduce(BigInt.new){|b, c| b*256+c}
  while big > 0
    r << T[(big%58).to_i32]
    big//= 58
  end
  r.reverse.join
end

def decode (string : String) : Bytes
  r= IO::Memory.new
  big= string.chars.reduce(BigInt.new){|b, c| b*58+(T.index(c)||(raise "nope!"))}
  while big > 0
    r.write_byte (big%256).to_u8
    big//= 256
  end
  r.to_slice.reverse!
end

```

If this seems to fit your needs, make sure before you use it for anything serious, that it works really always as you expect it, because I didn’t do so.

Also, depending on how often you have to use it, this likely won’t be the most performant option (BigInt does the job, but in this particular case it probably shouldn’t be your first choice should performance matter).

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [March 14, 2022, 3:25pm UTC](https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462/3 "2022-03-14T15:25:57Z")

</div>

Judging by GitHub code search, there are a number of base58 implementations available in Crystal: [Sign in to GitHub · GitHub](https://github.com/search?q=base58&type=code&l=Crystal)

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [March 14, 2022, 4:40pm UTC](https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462/4 "2022-03-14T16:40:05Z")

</div>

This is another implementation I wrote some time ago: [Carcin](https://carc.in/#/r/8w8w) (context: [Suggestion: Add Random#alphanumeric · Issue #8993 · crystal-lang/crystal · GitHub](https://github.com/crystal-lang/crystal/issues/8993#issuecomment-614048542)). It’s also based on `BigInt`, though because it uses a generic mechanism.

---

<div class="post-metadata">

**Author:** ![wout](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/wout/32/1578_2.png) [@wout](https://forum.crystal-lang.org/u/wout)\
**Post date:** [March 15, 2022, 7:54am UTC](https://forum.crystal-lang.org/t/how-to-implement-base58-to-bytes-in-crystal/4462/5 "2022-03-15T07:54:14Z")

</div>

Thank you both! Yesterday I went through all the base58 implementations for Ruby until I came across

[GitHub - dougal/base58: Base58 is a Ruby library/gem for converting ints to and from base58.](https://github.com/dougal/base58).

That lib made me realise I was using the wrong alphabet. [GitHub - russ/base58: base58 for Crystal](https://github.com/russ/base58) references the one used by Flickr, while I needed the one for Bitcoin.

I decided to port it to Crystal:

> **[GitHub - wout/base58: A Crystal shard for converting integers, bytes or...](https://github.com/wout/base58)**
>
> A Crystal shard for converting integers, bytes or binary-encoded strings, to and from Base58 using common alphabets. - GitHub - wout/base58: A Crystal shard for converting integers, bytes or binary...

Your solutions look more elegant, so if that’s ok with you, I’m going to rework the shard a bit starting off the examples above. Maybe rename it base\_x so it isn’t restricted to base58.
