This document describes two tags for the serialization of money amounts in Concise Binary Object Representation (CBOR, RFC7049).
Currency codes should be valid 3-letter codes from the ISO 4217 standard. CBOR encoders and decoders may reject invalid or unknown currency codes.
Multiple ways of serializing a quantity of money are allowed:
- As a UTF-8 string (major type 3), in base 10 with
.
(U+002E) as the decimal separator. That is, the string must match the Perl-compatible regular expression[0-9]+(\.[0-9]+)?
. - As an integer (major types 1 and 2).
- As a big number (tags 2 and 3).
- As a decimal fraction or big float (tags 4 and 5).
- As a rational number (tag 30).
- As an arbitrary-exponent number (tags 264 and 265).
- Data item: UTF-8 string (major type 3) or array (major type 4)
- Semantics: an amount of money, represented as a number and a currency code
The string representation is composed of a currency code (three uppercase letters) followed by a number. It must match the Perl-compatible regular expression [A-Z]{3}[0-9]+(\.[0-9]+)?
.
Examples:
"EUR10.00"
→DA00012D37 68 45555231302E3030
"JPY1300"
→DA00012D37 67 4A505931333030
The array representation is composed of two or three elements:
- The currency code (major type 3).
- The quantity of money (in any of the allowed formats listed in the previous section).
- A map (major type 5) of additional attributes attached to this amount of money. The map's keys should be text strings (major type 3) and a decoder should return an error if it encounters an attribute that it cannot attach to the re-created object.
Examples:
["EUR", "10.00"]
→DA00012D37 82 63 455552 65 31302E3030
["JPY", 1300, {"fuzzy": true}]
→DA00012D37 83 63 4A5059 19 0514 A1 65 66757A7A79 F5
- Data item: map (major type 5)
- Semantics: a set of money amounts in different currencies
The map's keys should be either currency codes or the special value "attrs"
.
If the key is a currency code, then the value must be a number serialized in one of the allowed formats previously listed.
If the key is "attrs"
, then the value must be a map (major type 5) of additional attributes attached to this basket. The map's keys should be text strings (major type 3) and a decoder should return an error if it encounters an attribute that it cannot attach to the re-created object.
Examples:
{"EUR": 10.00}
→DA00012D38 A1 63 455552 C4 82 21 1903E8
{"JPY": "1300", "USD": "11.22"}
→DA00012D38 A2 63 4A5059 64 31333030 63 555344 65 31312E3232
{"XAF": 0, "attrs": {"foo": "bar"}}
→DA00012D38 A2 63 584146 00 65 6174747273 A1 63 666F6F 63 626172
- Initial implementation: liberapay/utils/cbor.py#L42-L83
The tag number 77111 was chosen because it represents the first two letters of the word "Money" in ASCII.
The present document was written by Charly Coste (changaco at changaco.oy.lc) on 2019-02-22 and released on the same day under the terms of the CC0 Public Domain Dedication.