cab4cf13513d9153cead250e902c162a9cc99d22
3 * @author David Llewellyn-Jones <david@flypig.co.uk>
8 * Copyright David Llewellyn-Jones, 2020
9 * Released under the GPLv2.
11 * @brief Static utitlity functions.
12 * @section DESCRIPTION
14 * Provides various static utitlity functions. In particular:
16 * base64 encoding and decoding functionality.
17 * Time conversion: from epoch to day numbers and time interval numbers.
27 #include <openssl/evp.h>
33 // Function prototypes
35 // Function definitions
37 // Function definitions
40 * Returns the amount of space needed to store the base64 equivalent of a binary
43 * When converting to base64 it's often useful to know how much space will be
44 * needed to store the result, for example so that a buffer of the correct size
45 * can be allocated for it.
47 * This function returns the size needed for a buffer that will be large enough
48 * to store the result, including a terminating null character. The returned
49 * value may be larger than the size actually needed.
51 * @param binary_input The length of binary input that would be encoded.
52 * @return The buffer size needed to store the base64 version of the same data.
54 size_t base64_encode_size(size_t binary_input
) {
55 return (((size_t)((binary_input
+ 2) / 3)) * 4) + 1;
59 * Returns the amount of space needed to store the binary equivalent of a base64
62 * When converting from base64 it's often useful to know how much space will be
63 * needed to store the result, for example so that a buffer of the correct size
64 * can be allocated for it.
66 * This function returns the size needed for a buffer that will be large enough
67 * to store the result. The returned value may be larger than the size actually
70 * @param base64_input The length of a base64 string that would be decoded.
71 * @return The buffer size needed to store the binary version of the same data.
73 size_t base64_decode_size(size_t base64_input
) {
74 return (((size_t)((base64_input
+ 3) / 4)) * 3) + 1;
78 * Encodes binary data to base64 format string.
80 * Encodes the binary data provided into a base64 string, storing the result
81 * in the output buffer provided. The output buffer must be pre-allocated
82 * with enough space to store the result. The size needed can be found by
83 * calling the \ref base64_encode_size() function.
85 * If the output buffer is too small (based on the size provided) then the
86 * base64 string may be only partially written.
88 * @param input The binary data to encode. This doesn't need to be zero
90 * @param input_size The size of the input buffer to be converted.
91 * @param output A pre-allocated buffer to store the result.
92 * @param output_size The size of the allocated buffer, which will be updated
93 * to the number of bytes written to the buffer.
95 void base64_encode_binary_to_base64(unsigned char const *input
, size_t input_size
, unsigned char *output
, size_t *output_size
) {
100 size_out
= base64_encode_size(input_size
);
102 if (size_out
> *output_size
) {
103 size_in
= base64_decode_size(*output_size
- 1) - 1;
105 *output_size
= base64_encode_size(size_in
);
107 EVP_EncodeBlock(output
, input
, size_in
);
111 * Decodes a base64 string into the original binary data it represents.
113 * Decodes the base64 string provided into binary, storing the result in the
114 * output buffer provided. The output buffer must be pre-allocated with enough
115 * space to store the result. The size needed can be found by calling the
116 * \ref base64_decode_size() function.
118 * If the output buffer is too small (based on the size provided) then the
119 * binary output may be only partially written.
121 * @param input The base64 string to encode. This doesn't need to be zero
123 * @param input_size The size of the input buffer to be converted.
124 * @param output A pre-allocated buffer to store the result.
125 * @param output_size The size of the allocated buffer, which will be updated
126 * to the number of bytes written to the buffer.
128 void base64_decode_base64_to_binary(unsigned char const *input
, size_t input_size
, unsigned char *output
, size_t *output_size
) {
132 size_in
= input_size
;
133 size_out
= base64_decode_size(input_size
);
135 if (size_out
> *output_size
) {
136 size_in
= base64_encode_size(*output_size
- 1) - 1;
138 *output_size
= base64_decode_size(size_in
);
140 EVP_DecodeBlock(output
, input
, size_in
);
144 * Converts a time in epoch format into a day number.
146 * Returns the day number for the given epoch time. The epoch time represents
147 * the number of seconds since 00:00:00 UTC on 01/01/1970.
149 * The day number is calculated as:
150 * (Number of Seconds since Epoch) / (60 * 60 * 24)
152 * @param epoch The epoch time in seconds.
153 * @return The day number for this epoch time.
155 uint32_t epoch_to_day_number(time_t epoch
) {
158 // DayNumber <- (Number of Seconds since Epoch) / (60 * 60 * 24)
159 day_number
= epoch
/ (60 * 60 * 24);
165 * Converts a time in epoch format into a time interval number.
167 * Returns the time interval number for the given epoch time. The epoch time
168 * represents the number of seconds since 00:00:00 UTC on 01/01/1970.
170 * The time interval number is calculated as:
171 * (Seconds Since Start of DayNumber) / (60 * 10)
173 * and must fall in the interval [0, 143].
175 * @param epoch The epoch time in seconds.
176 * @return The time interval number for this epoch time.
178 uint8_t epoch_to_time_interval_number(time_t epoch
) {
179 uint8_t time_interval_number
;
183 // TimeNumberInterval <- (Seconds Since Start of DayNumber) / (60 * 10)
184 day_number
= epoch_to_day_number(epoch
);
185 seconds
= epoch
- (day_number
* (60 * 60 * 24));
187 time_interval_number
= seconds
/ (60 * 10);
189 // Falls in interval [0,143]
190 if (time_interval_number
> 143) {
191 time_interval_number
= 143;
194 return time_interval_number
;
197 /** @} addtogroup Utils */