]>
git.proxmox.com Git - rustc.git/blob - vendor/der/src/asn1/real.rs
1 //! ASN.1 `REAL` support.
3 // TODO(tarcieri): checked arithmetic
6 clippy
::cast_sign_loss
,
7 clippy
::integer_arithmetic
11 str_slice
::StrSlice
, ByteSlice
, DecodeValue
, EncodeValue
, FixedTag
, Header
, Length
, Reader
,
15 use super::integer
::uint
::strip_leading_zeroes
;
17 #[cfg_attr(docsrs, doc(cfg(feature = "real")))]
18 impl<'a
> DecodeValue
<'a
> for f64 {
19 fn decode_value
<R
: Reader
<'a
>>(reader
: &mut R
, header
: Header
) -> Result
<Self> {
20 let bytes
= ByteSlice
::decode_value(reader
, header
)?
.as_slice();
22 if header
.length
== Length
::ZERO
{
24 } else if is_nth_bit_one
::<7>(bytes
) {
25 // Binary encoding from section 8.5.7 applies
26 let sign
: u64 = if is_nth_bit_one
::<6>(bytes
) { 1 }
else { 0 }
;
28 // Section 8.5.7.2: Check the base -- the DER specs say that only base 2 should be supported in DER
29 let base
= mnth_bits_to_u8
::<5, 4>(bytes
);
32 // Real related error: base is not DER compliant (base encoded in enum)
33 return Err(Tag
::Real
.value_error());
37 let scaling_factor
= mnth_bits_to_u8
::<3, 2>(bytes
);
41 let exponent
= match mnth_bits_to_u8
::<1, 0>(bytes
) {
44 let ebytes
= (i16::from_be_bytes([0x0, bytes
[1]])).to_be_bytes();
45 u64::from_be_bytes([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ebytes
[0], ebytes
[1]])
49 let ebytes
= (i16::from_be_bytes([bytes
[1], bytes
[2]])).to_be_bytes();
50 u64::from_be_bytes([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ebytes
[0], ebytes
[1]])
53 // Real related error: encoded exponent cannot be represented on an IEEE-754 double
54 return Err(Tag
::Real
.value_error());
57 // Section 8.5.7.5: Read the remaining bytes for the mantissa
58 let mut n_bytes
= [0x0; 8];
59 for (pos
, byte
) in bytes
[mantissa_start
..].iter().rev().enumerate() {
60 n_bytes
[7 - pos
] = *byte
;
62 let n
= u64::from_be_bytes(n_bytes
);
63 // Multiply byt 2^F corresponds to just a left shift
64 let mantissa
= n
<< scaling_factor
;
66 Ok(encode_f64(sign
, exponent
, mantissa
))
67 } else if is_nth_bit_one
::<6>(bytes
) {
68 // This either a special value, or it's the value minus zero is encoded, section 8.5.9 applies
69 match mnth_bits_to_u8
::<1, 0>(bytes
) {
70 0 => Ok(f64::INFINITY
),
71 1 => Ok(f64::NEG_INFINITY
),
74 _
=> Err(Tag
::Real
.value_error()),
77 let astr
= StrSlice
::from_bytes(&bytes
[1..])?
;
78 match astr
.inner
.parse
::<f64>() {
80 // Real related error: encoding not supported or malformed
81 Err(_
) => Err(Tag
::Real
.value_error()),
87 #[cfg_attr(docsrs, doc(cfg(feature = "real")))]
88 impl EncodeValue
for f64 {
89 fn value_len(&self) -> Result
<Length
> {
90 if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE
{
91 // Zero: positive yet smaller than the minimum positive number
93 } else if self.is_nan()
95 || (self.is_sign_negative() && -self < f64::MIN_POSITIVE
)
97 // NaN, infinite (positive or negative), or negative zero (negative but its negative is less than the min positive number)
100 // The length is that of the first octets plus those needed for the exponent plus those needed for the mantissa
101 let (_sign
, exponent
, mantissa
) = decode_f64(*self);
103 let exponent_len
= if exponent
== 0 {
104 // Section 8.5.7.4: there must be at least one octet for exponent encoding
105 // But, if the exponent is zero, it'll be skipped, so we make sure force it to 1
108 let ebytes
= exponent
.to_be_bytes();
109 Length
::try_from(strip_leading_zeroes(&ebytes
).len())?
112 let mantissa_len
= if mantissa
== 0 {
115 let mbytes
= mantissa
.to_be_bytes();
116 Length
::try_from(strip_leading_zeroes(&mbytes
).len())?
119 exponent_len
+ mantissa_len
+ Length
::ONE
123 fn encode_value(&self, writer
: &mut dyn Writer
) -> Result
<()> {
124 // Check if special value
125 // Encode zero first, if it's zero
126 // Special value from section 8.5.9 if non zero
128 || self.is_infinite()
129 || (self.is_sign_negative() && -self < f64::MIN_POSITIVE
)
130 || (self.is_sign_positive() && (*self) < f64::MIN_POSITIVE
)
132 if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE
{
135 } else if self.is_nan() {
137 writer
.write_byte(0b0100_0010)?
;
138 } else if self.is_infinite() {
139 if self.is_sign_negative() {
141 writer
.write_byte(0b0100_0001)?
;
144 writer
.write_byte(0b0100_0000)?
;
148 writer
.write_byte(0b0100_0011)?
;
151 // Always use binary encoding, set bit 8 to 1
152 let mut first_byte
= 0b1000_0000;
154 if self.is_sign_negative() {
155 // Section 8.5.7.1: set bit 7 to 1 if negative
156 first_byte
|= 0b0100_0000;
159 // Bits 6 and 5 are set to 0 to specify that binary encoding is used
161 // NOTE: the scaling factor is only used to align the implicit point of the mantissa.
162 // This is unnecessary in DER because the base is 2, and therefore necessarily aligned.
163 // Therefore, we do not modify the mantissa in anyway after this function call, which
164 // already adds the implicit one of the IEEE 754 representation.
165 let (_sign
, exponent
, mantissa
) = decode_f64(*self);
167 // Encode the exponent as two's complement on 16 bits and remove the bias
168 let exponent_bytes
= exponent
.to_be_bytes();
169 let ebytes
= strip_leading_zeroes(&exponent_bytes
);
173 2 => first_byte
|= 0b0000_0001,
174 3 => first_byte
|= 0b0000_0010,
176 // TODO: support multi octet exponent encoding?
177 return Err(Tag
::Real
.value_error());
181 writer
.write_byte(first_byte
)?
;
183 // Encode both bytes or just the last one, handled by encode_bytes directly
184 // Rust already encodes the data as two's complement, so no further processing is needed
185 writer
.write(ebytes
)?
;
187 // Now, encode the mantissa as unsigned binary number
188 let mantissa_bytes
= mantissa
.to_be_bytes();
189 let mbytes
= strip_leading_zeroes(&mantissa_bytes
);
190 writer
.write(mbytes
)?
;
197 #[cfg_attr(docsrs, doc(cfg(feature = "real")))]
198 impl FixedTag
for f64 {
199 const TAG
: Tag
= Tag
::Real
;
202 /// Is the N-th bit 1 in the first octet?
203 /// NOTE: this function is zero indexed
204 pub(crate) fn is_nth_bit_one
<const N
: usize>(bytes
: &[u8]) -> bool
{
208 .map(|byte
| byte
& (1 << N
) != 0)
215 /// Convert bits M, N into a u8, in the first octet only
216 pub(crate) fn mnth_bits_to_u8
<const M
: usize, const N
: usize>(bytes
: &[u8]) -> u8 {
217 let bit_m
= is_nth_bit_one
::<M
>(bytes
);
218 let bit_n
= is_nth_bit_one
::<N
>(bytes
);
219 (bit_m
as u8) << 1 | bit_n
as u8
222 /// Decode an f64 as its sign, exponent, and mantissa in u64 and in that order, using bit shifts and masks.
223 /// Note: this function **removes** the 1023 bias from the exponent and adds the implicit 1
224 #[allow(clippy::cast_possible_truncation)]
225 pub(crate) fn decode_f64(f
: f64) -> (u64, u64, u64) {
226 let bits
= f
.to_bits();
227 let sign
= bits
>> 63;
228 let exponent
= bits
>> 52 & 0x7ff;
229 let exponent_bytes_no_bias
= (exponent
as i16 - 1023).to_be_bytes();
230 let exponent_no_bias
= u64::from_be_bytes([
237 exponent_bytes_no_bias
[0],
238 exponent_bytes_no_bias
[1],
240 let mantissa
= bits
& 0xfffffffffffff;
241 (sign
, exponent_no_bias
, mantissa
+ 1)
244 /// Encode an f64 from its sign, exponent (**without** the 1023 bias), and (mantissa - 1) using bit shifts as received by ASN1
245 pub(crate) fn encode_f64(sign
: u64, exponent
: u64, mantissa
: u64) -> f64 {
246 // Add the bias to the exponent
247 let exponent_with_bias
=
248 (i16::from_be_bytes([exponent
.to_be_bytes()[6], exponent
.to_be_bytes()[7]]) + 1023) as u64;
249 let bits
= sign
<< 63 | exponent_with_bias
<< 52 | (mantissa
- 1);
255 use crate::{Decode, Encode}
;
258 fn decode_subnormal() {
259 assert
!(f64::from_der(&[0x09, 0x01, 0b0100_0010]).unwrap().is_nan());
260 let plus_infty
= f64::from_der(&[0x09, 0x01, 0b0100_0000]).unwrap();
261 assert
!(plus_infty
.is_infinite() && plus_infty
.is_sign_positive());
262 let neg_infty
= f64::from_der(&[0x09, 0x01, 0b0100_0001]).unwrap();
263 assert
!(neg_infty
.is_infinite() && neg_infty
.is_sign_negative());
264 let neg_zero
= f64::from_der(&[0x09, 0x01, 0b0100_0011]).unwrap();
265 assert
!(neg_zero
.is_sign_negative() && neg_zero
.abs() < f64::EPSILON
);
269 fn encode_subnormal() {
270 // All subnormal fit in three bytes
271 let mut buffer
= [0u8; 3];
273 &[0x09, 0x01, 0b0100_0010],
274 f64::NAN
.encode_to_slice(&mut buffer
).unwrap()
277 &[0x09, 0x01, 0b0100_0000],
278 f64::INFINITY
.encode_to_slice(&mut buffer
).unwrap()
281 &[0x09, 0x01, 0b0100_0001],
282 f64::NEG_INFINITY
.encode_to_slice(&mut buffer
).unwrap()
285 &[0x09, 0x01, 0b0100_0011],
286 (-0.0_f64).encode_to_slice(&mut buffer
).unwrap()
292 // The comments correspond to the decoded value from the ASN.1 playground when the bytes are inputed.
296 let expected
= &[0x09, 0x0];
297 let mut buffer
= [0u8; 2];
298 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
301 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
302 val
, encoded
, expected
304 let decoded
= f64::from_der(encoded
).unwrap();
306 (decoded
- val
).abs() < f64::EPSILON
,
307 "wanted: {}\tgot: {}",
314 // rec1value R ::= { mantissa 1, base 2, exponent 0 }
316 let expected
= &[0x09, 0x03, 0x80, 0x00, 0x01];
317 let mut buffer
= [0u8; 5];
318 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
321 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
322 val
, encoded
, expected
324 let decoded
= f64::from_der(encoded
).unwrap();
326 (decoded
- val
).abs() < f64::EPSILON
,
327 "wanted: {}\tgot: {}",
334 // rec1value R ::= { mantissa -1, base 2, exponent 0 }
336 let expected
= &[0x09, 0x03, 0xc0, 0x00, 0x01];
337 let mut buffer
= [0u8; 5];
338 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
341 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
342 val
, encoded
, expected
344 let decoded
= f64::from_der(encoded
).unwrap();
346 (decoded
- val
).abs() < f64::EPSILON
,
347 "wanted: {}\tgot: {}",
354 // rec1value R ::= { mantissa -1, base 2, exponent 1 }
355 let val
= -1.0000000000000002;
356 let expected
= &[0x09, 0x03, 0xc0, 0x00, 0x02];
357 let mut buffer
= [0u8; 5];
358 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
361 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
362 val
, encoded
, expected
364 let decoded
= f64::from_der(encoded
).unwrap();
366 (decoded
- val
).abs() < f64::EPSILON
,
367 "wanted: {}\tgot: {}",
374 // rec1value R ::= { mantissa 1, base 2, exponent -1022 }
375 // NOTE: f64::MIN_EXP == -1021 so the exponent decoded by ASN.1 is what we expect
376 let val
= f64::MIN_POSITIVE
;
377 let expected
= &[0x09, 0x04, 0x81, 0xfc, 0x02, 0x01];
378 let mut buffer
= [0u8; 7];
379 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
382 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
383 val
, encoded
, expected
385 let decoded
= f64::from_der(encoded
).unwrap();
387 (decoded
- val
).abs() < f64::EPSILON
,
388 "wanted: {}\tgot: {}",
395 // rec4value R ::= { mantissa 1, base 2, exponent 3 }
396 let val
= 1.0000000000000016;
397 let expected
= &[0x09, 0x03, 0x80, 0x00, 0x08];
398 let mut buffer
= [0u8; 5];
399 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
402 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
403 val
, encoded
, expected
405 let decoded
= f64::from_der(encoded
).unwrap();
407 (decoded
- val
).abs() < f64::EPSILON
,
408 "wanted: {}\tgot: {}",
415 // rec5value R ::= { mantissa 4222124650659841, base 2, exponent 4 }
418 0x9, 0x9, 0x80, 0x04, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
420 let mut buffer
= [0u8; 11];
421 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
424 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
425 val
, encoded
, expected
427 let decoded
= f64::from_der(encoded
).unwrap();
429 (decoded
- val
).abs() < f64::EPSILON
,
430 "wanted: {}\tgot: {}",
438 fn encdec_irrationals() {
440 let val
= core
::f64::consts
::PI
;
442 0x09, 0x09, 0x80, 0x01, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x19,
444 let mut buffer
= [0u8; 11];
445 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
448 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
449 val
, encoded
, expected
451 let decoded
= f64::from_der(encoded
).unwrap();
453 (decoded
- val
).abs() < f64::EPSILON
,
454 "wanted: {}\tgot: {}",
461 let val
= core
::f64::consts
::E
;
463 0x09, 0x09, 0x80, 0x01, 0x05, 0xbf, 0x0a, 0x8b, 0x14, 0x57, 0x6a,
465 let mut buffer
= [0u8; 12];
466 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
469 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
470 val
, encoded
, expected
472 let decoded
= f64::from_der(encoded
).unwrap();
474 (decoded
- val
).abs() < f64::EPSILON
,
475 "wanted: {}\tgot: {}",
481 let val
= core
::f64::consts
::LN_2
;
483 0x09, 0x0a, 0x81, 0xff, 0xff, 0x6, 0x2e, 0x42, 0xfe, 0xfa, 0x39, 0xf0,
485 let mut buffer
= [0u8; 12];
486 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
489 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
490 val
, encoded
, expected
492 let decoded
= f64::from_der(encoded
).unwrap();
494 (decoded
- val
).abs() < f64::EPSILON
,
495 "wanted: {}\tgot: {}",
503 fn encdec_reasonable_f64() {
504 // Tests the encoding and decoding of reals with some arbitrary numbers
506 // rec1value R ::= { mantissa 2414341043715239, base 2, exponent 21 }
507 let val
= 3221417.1584163485;
509 0x9, 0x9, 0x80, 0x15, 0x8, 0x93, 0xd4, 0x94, 0x46, 0xfc, 0xa7,
511 let mut buffer
= [0u8; 11];
512 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
515 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
516 val
, encoded
, expected
518 let decoded
= f64::from_der(encoded
).unwrap();
520 (decoded
- val
).abs() < f64::EPSILON
,
521 "wanted: {}\tgot: {}",
528 // rec1value R ::= { mantissa 2671155248072715, base 2, exponent 23 }
529 let val
= 13364022.365665454;
531 0x09, 0x09, 0x80, 0x17, 0x09, 0x7d, 0x66, 0xcb, 0xb3, 0x88, 0x0b,
533 let mut buffer
= [0u8; 12];
534 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
537 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
538 val
, encoded
, expected
540 let decoded
= f64::from_der(encoded
).unwrap();
542 (decoded
- val
).abs() < f64::EPSILON
,
543 "wanted: {}\tgot: {}",
550 // rec1value R ::= { mantissa -4386812962460287, base 2, exponent 14 }
551 let val
= -32343.132588105735;
553 0x09, 0x09, 0xc0, 0x0e, 0x0f, 0x95, 0xc8, 0x7c, 0x52, 0xd2, 0x7f,
555 let mut buffer
= [0u8; 12];
556 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
559 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
560 val
, encoded
, expected
562 let decoded
= f64::from_der(encoded
).unwrap();
564 (decoded
- val
).abs() < f64::EPSILON
,
565 "wanted: {}\tgot: {}",
572 let val
= -27084.866751869475;
574 0x09, 0x09, 0xc0, 0x0e, 0x0a, 0x73, 0x37, 0x78, 0xdc, 0xd5, 0x4a,
576 let mut buffer
= [0u8; 12];
577 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
580 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
581 val
, encoded
, expected
583 let decoded
= f64::from_der(encoded
).unwrap();
585 (decoded
- val
).abs() < f64::EPSILON
,
586 "wanted: {}\tgot: {}",
593 // rec1value R ::= { mantissa -4372913134428149, base 2, exponent 7 }
594 let val
= -252.28566647111404;
596 0x09, 0x09, 0xc0, 0x07, 0x0f, 0x89, 0x24, 0x2e, 0x02, 0xdf, 0xf5,
598 let mut buffer
= [0u8; 12];
599 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
602 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
603 val
, encoded
, expected
605 let decoded
= f64::from_der(encoded
).unwrap();
607 (decoded
- val
).abs() < f64::EPSILON
,
608 "wanted: {}\tgot: {}",
615 let val
= -14.399709612928548;
617 0x09, 0x09, 0xc0, 0x03, 0x0c, 0xcc, 0xa6, 0xbd, 0x06, 0xd9, 0x92,
619 let mut buffer
= [0u8; 12];
620 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
623 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
624 val
, encoded
, expected
626 let decoded
= f64::from_der(encoded
).unwrap();
628 (decoded
- val
).abs() < f64::EPSILON
,
629 "wanted: {}\tgot: {}",
636 let val
= -0.08340570261832964;
638 0x09, 0x0a, 0xc1, 0xff, 0xfc, 0x05, 0x5a, 0x13, 0x7d, 0x0b, 0xae, 0x3d,
640 let mut buffer
= [0u8; 12];
641 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
644 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
645 val
, encoded
, expected
647 let decoded
= f64::from_der(encoded
).unwrap();
649 (decoded
- val
).abs() < f64::EPSILON
,
650 "wanted: {}\tgot: {}",
657 let val
= 0.00536851453803701;
659 0x09, 0x0a, 0x81, 0xff, 0xf8, 0x05, 0xfd, 0x4b, 0xa5, 0xe7, 0x4c, 0x93,
661 let mut buffer
= [0u8; 12];
662 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
665 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
666 val
, encoded
, expected
668 let decoded
= f64::from_der(encoded
).unwrap();
670 (decoded
- val
).abs() < f64::EPSILON
,
671 "wanted: {}\tgot: {}",
678 let val
= 0.00045183525648866433;
680 0x09, 0x0a, 0x81, 0xff, 0xf4, 0x0d, 0x9c, 0x89, 0xa6, 0x59, 0x33, 0x39,
682 let mut buffer
= [0u8; 12];
683 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
686 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
687 val
, encoded
, expected
689 let decoded
= f64::from_der(encoded
).unwrap();
691 (decoded
- val
).abs() < f64::EPSILON
,
692 "wanted: {}\tgot: {}",
699 let val
= 0.000033869092002682955;
701 0x09, 0x0a, 0x81, 0xff, 0xf1, 0x01, 0xc1, 0xd5, 0x23, 0xd5, 0x54, 0x7c,
703 let mut buffer
= [0u8; 12];
704 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
707 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
708 val
, encoded
, expected
710 let decoded
= f64::from_der(encoded
).unwrap();
712 (decoded
- val
).abs() < f64::EPSILON
,
713 "wanted: {}\tgot: {}",
720 let val
= 0.0000011770891033600088;
722 0x09, 0x0a, 0x81, 0xff, 0xec, 0x03, 0xbf, 0x8f, 0x27, 0xf4, 0x62, 0x56,
724 let mut buffer
= [0u8; 12];
725 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
728 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
729 val
, encoded
, expected
731 let decoded
= f64::from_der(encoded
).unwrap();
733 (decoded
- val
).abs() < f64::EPSILON
,
734 "wanted: {}\tgot: {}",
741 let val
= 0.00000005549514041997082;
743 0x09, 0x0a, 0x81, 0xff, 0xe7, 0x0d, 0xcb, 0x31, 0xab, 0x6e, 0xb8, 0xd7,
745 let mut buffer
= [0u8; 12];
746 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
749 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
750 val
, encoded
, expected
752 let decoded
= f64::from_der(encoded
).unwrap();
754 (decoded
- val
).abs() < f64::EPSILON
,
755 "wanted: {}\tgot: {}",
762 let val
= 0.0000000012707044685547803;
764 0x09, 0x0a, 0x81, 0xff, 0xe2, 0x05, 0xd4, 0x9e, 0x0a, 0xf2, 0xff, 0x1f,
766 let mut buffer
= [0u8; 12];
767 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
770 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
771 val
, encoded
, expected
773 let decoded
= f64::from_der(encoded
).unwrap();
775 (decoded
- val
).abs() < f64::EPSILON
,
776 "wanted: {}\tgot: {}",
783 let val
= 0.00000000002969611878378562;
785 0x09, 0x09, 0x81, 0xff, 0xdd, 0x53, 0x5b, 0x6f, 0x97, 0xee, 0xb6,
787 let mut buffer
= [0u8; 11];
788 let encoded
= val
.encode_to_slice(&mut buffer
).unwrap();
791 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
792 val
, encoded
, expected
794 let decoded
= f64::from_der(encoded
).unwrap();
796 (decoded
- val
).abs() < f64::EPSILON
,
797 "wanted: {}\tgot: {}",
805 fn reject_non_canonical() {
806 assert
!(f64::from_der(&[0x09, 0x81, 0x00]).is_err());
811 use super::{decode_f64, encode_f64}
;
812 // Test that the extraction and recreation works
827 let (s
, e
, m
) = decode_f64(val
);
828 let val2
= encode_f64(s
, e
, m
);
830 (val
- val2
).abs() < f64::EPSILON
,
831 "fail - want {}\tgot {}",
839 fn validation_cases() {
840 // Caveat: these test cases are validated on the ASN.1 playground: https://asn1.io/asn1playground/ .
841 // The test case consists in inputing the bytes in the "decode" field and checking that the decoded
842 // value corresponds to the one encoded here.
843 // This tool encodes _all_ values that are non-zero in the ISO 6093 NR3 representation.
844 // This does not seem to perfectly adhere to the ITU specifications, Special Cases section.
845 // The implementation of this crate correctly supports decoding such values. It will, however,
846 // systematically encode REALs in their base 2 form, with a scaling factor where needed to
847 // ensure that the mantissa is either odd or zero (as per section 11.3.1).
849 // Positive trivial numbers
852 let testcase
= &[0x09, 0x05, 0x03, 0x31, 0x2E, 0x45, 0x31];
853 let decoded
= f64::from_der(testcase
).unwrap();
855 (decoded
- expect
).abs() < f64::EPSILON
,
856 "wanted: {}\tgot: {}",
863 let testcase
= &[0x09, 0x05, 0x03, 0x31, 0x2E, 0x45, 0x32];
864 let decoded
= f64::from_der(testcase
).unwrap();
866 (decoded
- expect
).abs() < f64::EPSILON
,
867 "wanted: {}\tgot: {}",
874 let testcase
= &[0x09, 0x08, 0x03, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30];
875 let decoded
= f64::from_der(testcase
).unwrap();
877 (decoded
- expect
).abs() < f64::EPSILON
,
878 "wanted: {}\tgot: {}",
885 let testcase
= &[0x09, 0x08, 0x03, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30];
886 let decoded
= f64::from_der(testcase
).unwrap();
888 (decoded
- expect
).abs() < f64::EPSILON
,
889 "wanted: {}\tgot: {}",
896 let testcase
= &[0x09, 0x00];
897 let decoded
= f64::from_der(testcase
).unwrap();
899 (decoded
- expect
).abs() < f64::EPSILON
,
900 "wanted: {}\tgot: {}",
906 let expect
= 951.2357864;
908 0x09, 0x0F, 0x03, 0x39, 0x35, 0x31, 0x32, 0x33, 0x35, 0x37, 0x38, 0x36, 0x34, 0x2E,
911 let decoded
= f64::from_der(testcase
).unwrap();
913 (decoded
- expect
).abs() < f64::EPSILON
,
914 "wanted: {}\tgot: {}",
919 // Negative trivial numbers
922 let testcase
= &[0x09, 0x06, 0x03, 0x2D, 0x31, 0x2E, 0x45, 0x31];
923 let decoded
= f64::from_der(testcase
).unwrap();
925 (decoded
- expect
).abs() < f64::EPSILON
,
926 "wanted: {}\tgot: {}",
933 let testcase
= &[0x09, 0x06, 0x03, 0x2D, 0x31, 0x2E, 0x45, 0x32];
934 let decoded
= f64::from_der(testcase
).unwrap();
936 (decoded
- expect
).abs() < f64::EPSILON
,
937 "wanted: {}\tgot: {}",
945 0x09, 0x09, 0x03, 0x2D, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30,
947 let decoded
= f64::from_der(testcase
).unwrap();
949 (decoded
- expect
).abs() < f64::EPSILON
,
950 "wanted: {}\tgot: {}",
957 let testcase
= &[0x09, 0x07, 0x03, 0x2D, 0x35, 0x2E, 0x45, 0x2D, 0x31];
958 let decoded
= f64::from_der(testcase
).unwrap();
960 (decoded
- expect
).abs() < f64::EPSILON
,
961 "wanted: {}\tgot: {}",
968 let testcase
= &[0x09, 0x03, 0x01, 0x2D, 0x30];
969 let decoded
= f64::from_der(testcase
).unwrap();
971 (decoded
- expect
).abs() < f64::EPSILON
,
972 "wanted: {}\tgot: {}",
979 let expect
= -951.2357864;
981 0x09, 0x10, 0x03, 0x2D, 0x39, 0x35, 0x31, 0x32, 0x33, 0x35, 0x37, 0x38, 0x36, 0x34,
982 0x2E, 0x45, 0x2D, 0x37,
984 let decoded
= f64::from_der(testcase
).unwrap();
986 (decoded
- expect
).abs() < f64::EPSILON
,
987 "wanted: {}\tgot: {}",