Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/PyNaCl-1.6.0.dev1-py3.8-linux-x86_64.egg/nacl/encoding.py: 82%

57 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-06 06:06 +0000

1# Copyright 2013 Donald Stufft and individual contributors 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14import base64 

15import binascii 

16from abc import ABCMeta, abstractmethod 

17from typing import SupportsBytes, Type 

18 

19 

20# TODO: when the minimum supported version of Python is 3.8, we can import 

21# Protocol from typing, and replace Encoder with a Protocol instead. 

22class _Encoder(metaclass=ABCMeta): 

23 @staticmethod 

24 @abstractmethod 

25 def encode(data: bytes) -> bytes: 

26 """Transform raw data to encoded data.""" 

27 

28 @staticmethod 

29 @abstractmethod 

30 def decode(data: bytes) -> bytes: 

31 """Transform encoded data back to raw data. 

32 

33 Decoding after encoding should be a no-op, i.e. `decode(encode(x)) == x`. 

34 """ 

35 

36 

37# Functions that use encoders are passed a subclass of _Encoder, not an instance 

38# (because the methods are all static). Let's gloss over that detail by defining 

39# an alias for Type[_Encoder]. 

40Encoder = Type[_Encoder] 

41 

42 

43class RawEncoder(_Encoder): 

44 @staticmethod 

45 def encode(data: bytes) -> bytes: 

46 return data 

47 

48 @staticmethod 

49 def decode(data: bytes) -> bytes: 

50 return data 

51 

52 

53class HexEncoder(_Encoder): 

54 @staticmethod 

55 def encode(data: bytes) -> bytes: 

56 return binascii.hexlify(data) 

57 

58 @staticmethod 

59 def decode(data: bytes) -> bytes: 

60 return binascii.unhexlify(data) 

61 

62 

63class Base16Encoder(_Encoder): 

64 @staticmethod 

65 def encode(data: bytes) -> bytes: 

66 return base64.b16encode(data) 

67 

68 @staticmethod 

69 def decode(data: bytes) -> bytes: 

70 return base64.b16decode(data) 

71 

72 

73class Base32Encoder(_Encoder): 

74 @staticmethod 

75 def encode(data: bytes) -> bytes: 

76 return base64.b32encode(data) 

77 

78 @staticmethod 

79 def decode(data: bytes) -> bytes: 

80 return base64.b32decode(data) 

81 

82 

83class Base64Encoder(_Encoder): 

84 @staticmethod 

85 def encode(data: bytes) -> bytes: 

86 return base64.b64encode(data) 

87 

88 @staticmethod 

89 def decode(data: bytes) -> bytes: 

90 return base64.b64decode(data) 

91 

92 

93class URLSafeBase64Encoder(_Encoder): 

94 @staticmethod 

95 def encode(data: bytes) -> bytes: 

96 return base64.urlsafe_b64encode(data) 

97 

98 @staticmethod 

99 def decode(data: bytes) -> bytes: 

100 return base64.urlsafe_b64decode(data) 

101 

102 

103class Encodable: 

104 def encode(self: SupportsBytes, encoder: Encoder = RawEncoder) -> bytes: 

105 return encoder.encode(bytes(self))