前回の続き。
明示的にリンクする必要のあるライブラリであるOpenSSLを使ってstd.digest.sha
を使わずにSHA256を計算する。
自分みたいな初心者のための基礎的な記事を量産することを目標にしているので、細かい手順をできるだけ詳細に具体的に書いていきたい。
1 - dub init
前回と同じ。
$ tree
.
├── dub.json
└── source
└── app.d
1 directory, 2 files
2 - 宣言を探す
OpenSSLはインストール済みとする。
/usr/include/openssl/sha.h
を読んでみる。
$ cat /usr/include/openssl/sha.h | grep SHA256
# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a
# define SHA256_DIGEST_LENGTH 32
typedef struct SHA256state_st {
} SHA256_CTX;
# ifndef OPENSSL_NO_SHA256
int private_SHA224_Init(SHA256_CTX *c);
int private_SHA256_Init(SHA256_CTX *c);
int SHA224_Init(SHA256_CTX *c);
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA224_Final(unsigned char *md, SHA256_CTX *c);
int SHA256_Init(SHA256_CTX *c);
int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA256_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
$ cat /usr/include/openssl/sha.h | grep SHA256_DIGEST_LENGTH
# define SHA256_DIGEST_LENGTH 32
今回は
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
と
# define SHA256_DIGEST_LENGTH 32
を使えるようにする。
3 - 宣言
source/sha.d
(New File)
/// C : # define SHA256_DIGEST_LENGTH 32
enum SHA256_DIGEST_LENGTH = 32;
/// C : unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
extern (C) ubyte* SHA256(const ubyte* d, size_t n, ubyte* md);
unsigned char
はubyte
と対応している。
4 - 使う
source/app.d
import std.stdio : writeln;
import std.digest.digest : toHexString;
import sha;
void main()
{
string text = "The quick brown fox jumps over the lazy dog";
ubyte[SHA256_DIGEST_LENGTH] hash;
SHA256(cast(const ubyte*) &text[0], text.length, cast(ubyte*) &hash[0]);
assert(hash.toHexString() == "D7A8FBB307D7809469CA9ABCB0082E4F8D5651E46D3CDB762D02D0BF37C9E592");
hash.toHexString.writeln();
}
入力文字列とその結果はこちらのサイトから引用した。 このサイトの引用元はリンクが切れてしまっているようだ。
5 - リンクするライブラリの指定
dub.json
{
"name": "shatest",
"authors": [
"kotet"
],
"description": "A minimal D application.",
"copyright": "Copyright © 2017, kotet",
"license": "proprietary",
"libs": [
"openssl"
]
}
libs
に外部ライブラリの名前を渡すとリンカオプションになる。
6 - 完成
$ dub build
Performing "debug" build using dmd for x86_64.
shatest ~master: building configuration "application"...
Linking...
$ ./shatest
D7A8FBB307D7809469CA9ABCB0082E4F8D5651E46D3CDB762D02D0BF37C9E592