top page > computer > web > rfc > x_690 > 8_1_common > coding > existential > data_encode.html
更新日:
文責: 重城良国

X.690: ASN.1のBER方式の共通部分の存在型を利用したデコード関数のためのデータ型

AsnableNg.hs

AsnableクラスへのencodeDer関数の追加

AsnableクラスにDER形式でエンコードする関数を追加した。

class Asnable a where
	getAsn1Tag :: a -> Asn1Tag
	encodeDer :: a -> ByteString

AsnableBoxに対するencodeDer関数の追加

AsnableBoxをエンコードするには、中身をエンコードすれば良い。

instance Asnable AsnableBox where
	getAsn1Tag (AsnableBox a) = getAsn1Tag a
	encodeDer (AsnableBox a) = encodeDer a

RawBytes型の追加

一度読み込んだタグやデータ長を最度バイト列に追加して一塊のデータとすることが必要な場合がある。そのためのデータ構造をRawBytes型とした。

data RawBytes = RawBytes ByteString
	deriving (Show, Typeable)

基本的な型に対するencodeDer関数

RawBytesはすでにencodeDerされていると考えられる。

instance Asnable RawBytes where
	getAsn1Tag (RawBytes bs) = let
		Right (t, _) = runAnalyzer decodeTag bs in t
	encodeDer (RawBytes bs) = bs

タグとデータ長を表すバイト列を追加すれば良い。

instance Asnable Raw where
	getAsn1Tag (Raw t _) = t
	encodeDer (Raw t bs) = encodeTag t
		`append` encodeLength
			(Just . fromIntegral $ length bs)
		`append` bs

下位のAsnableBoxを復号したうえでタグとデータ長を示すバイト列を追加する。

instance Asnable RawConstructed where
	getAsn1Tag (RawConstructed t _) = t
	encodeDer (RawConstructed t as) = encodeTag t
		`append` encodeLength
			(Just . fromIntegral $ length bs)
		where
		bs = concat $ map encodeDer as

その他の型に対するencodeDer関数

instance Asnable a => Asnable [a] where
	getAsn1Tag _ = Asn1Tag Universal Constructed 16
	encodeDer as = encodeTag (getAsn1Tag as)
		`append` encodeLength
			(Just . fromIntegral $ length bs)
		`append` bs
		where
		bs = concat $ map encodeDer as
instance Asnable Bool where
	getAsn1Tag _ = Asn1Tag Universal Primitive 1
	encodeDer b = encodeTag (getAsn1Tag b)
		`append` encodeLength (Just 1)
		`append` (if b then "\xff" else "\x00")
instance Asnable Integer where
	getAsn1Tag _ = Asn1Tag Universal Primitive 2
	encodeDer n = encodeTag (getAsn1Tag n)
		`append` encodeLength
			(Just . fromIntegral $ length bs')
		`append` bs'
		where
		bs' = pack $ if testBit b 7 then 0 : bs else bs
		bs@(b : _)	| 0 <- n = [0]
				| otherwise = reverse $
					integerToWord8s n

試してみる

testAsnableNg.hs

% ghci testAsnableNg.hs
Main> :set -XOverloadedStrings
Main> let Right (ab, "") = decodeWith [Rule integerRule,
Rule sequenceRule, Rule recRule] cert
Main> decodeDer ab
"0\130...
Main> it == cert
True

「タグと長さのエンコード」へもどる 「ルールをクラスに」へ

正当なCSSです! HTML5 Powered with CSS3 / styling, and Semantics