/*	
 *	clipcode.h
 *
 *	文字コード処理
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2009 Naoyuki Sawa
 *
 *	* Mon Feb 19 00:05:57 JST 2007 Naoyuki Sawa
 *	- 1st リリース。
 *	* Sun Nov 16 12:58:50 JST 2008 Naoyuki Sawa
 *	- url_encode()、url_decode()を追加しました。
 *	* Tue Jan 06 14:21:36 JST 2009 Naoyuki Sawa
 *	- md5_digest()を追加しました。
 *	* Wed Jan 07 16:23:27 JST 2009 Naoyuki Sawa
 *	- sha1_digest()を追加しました。
 *	* Thu Jan 15 16:13:35 JST 2009 Naoyuki Sawa
 *	- rc4_init()、rc4_encrypt_decrypt()を追加しました。
 */
#ifndef __CLIP_CODE_H__
#define __CLIP_CODE_H__

/****************************************************************************
 *	Base64
 ****************************************************************************/

/* バイナリをBase64エンコードし、文字列に変換します。
 * [in]
 *	dst		文字列。(出力)
 *	dst_cap		dst[]の許容量。
 *	src		バイナリ。(入力)
 *	src_len		src[]の要素数。
 * [out]
 *	戻り値		文字列の長さ。
 *			終端のnul文字は、文字列の長さに含めません。
 * [note]
 *	* 出力文字列はnul終端されます。
 *	  ただし、戻り値はnul文字を含まないことに注意してください。
 *	  <例>
 *		[in]
 *			dst[]		unsigned char dst[100]
 *			dst_len		100
 *			src[]		{ 0x12,0x34 }
 *			src_len		2
 *		[out]
 *			dst[]		"EjQ=" // { 'E','j','Q','=','\0' }
 *			戻り値		4
 *		[note]
 *			戻り値は文字数の4ですが、出力はnul終端を含めて5バイトです。
 *			もし、dst_lenが5未満だったならば、アサートします。
 *	* 戻り値は、strlen(dst)に一致するので、あとで算出することもできます。
 *	  文字列の長さがすぐに必要なければ、戻り値を受け取らなくても構いません。
 */
int base64_encode(char* dst, int dst_cap, const void* src, int src_len);

/* 文字列をBase64デコードし、バイナリに変換します。
 * [in]
 *	dst		バイナリ。(出力)
 *	dst_cap		dst[]の許容量。
 *	src		文字列。(入力)
 * [out]
 *	戻り値		バイナリの長さ。
 * [note]
 *	* 出力バイナリはnul終端されません。
 *	  出力バイナリそれ自身が、有意な値「0」を含む可能性があるからです。
 *	  <例>
 *		[in]
 *			dst[]		unsigned char dst[100]
 *			dst_len		100
 *			src[]		"EjQ=" // { 'E','j','Q','=','\0' }
 *		[out]
 *			dst[]		{ 0x12,0x34 }
 *			戻り値		2
 *		[note]
 *			もし、dst_lenが2未満だったならば、アサートします。
 *	* 出力バイナリの長さを、あとで算出することはできません。
 *	  base64_encode()の場合と違って、必ず、戻り値を受け取ってください。
 */
int base64_decode(void* _dst, int dst_cap, const char* src);

/****************************************************************************
 *	URLエンコード
 ****************************************************************************/

/* 任意の文字列を、URLエンコードされた文字列に変換します。
 * [in]
 *	dst		出力バッファ。
 *	dst_size	出力バッファのバイト数。
 *	src		任意の文字列。
 * [out]
 *	戻り値		出力した文字数。
 *			末端の'\0'は含めません。
 */
int url_encode(char* dst, int dst_size, const char* src);

/* URLエンコードされた文字列を、元の文字列に変換します。
 * [in]
 *	dst		出力バッファ。
 *	dst_size	出力バッファのバイト数。
 *	src		URLエンコードされた文字列。
 * [out]
 *	戻り値		出力した文字数。
 *			末端の'\0'は含めません。
 */
int url_decode(char* dst, int dst_size, const char* src);

/****************************************************************************
 *	MD5
 ****************************************************************************/

/* バイナリデータの、MD5ダイジェストを求めます。
 * [in]
 *	digest		MD5ダイジェストを格納するバッテァ。(出力)
 *	data		バイナリデータ。(入力)
 *	len		バイナリデータのバイト数。(>=0)
 * [out]
 *	digest		MD5ダイジェストを格納します。
 * [note]
 *	* 以下の資料を参考にしました。
 *	  「MD5 メッセージダイジェストアルゴリズム」(The MD5 Message-Digest Algorithm)
 *	   (URL: http://www.ipa.go.jp/security/rfc/RFC1321JA.html)
 *	- 本関数は、上記資料内のサンプル実装プログラムを簡略化して、実装したものです。
 *	  簡略化した点は、以下の二点です。
 *	  ・実行環境のバイトオーダーが、リトルエンディアンであるものと決め打ちました。
 *	  ・データストリームに対して繰り返し呼び出すのでなく、
 *	    メモリ上のデータブロックに対して一回の呼び出しで求める用途に限定しました。
 */
void md5_digest(unsigned char digest[/*16*/], const void* data, int len);

/****************************************************************************
 *	SHA-1
 ****************************************************************************/

/* バイナリデータの、SHA-1ダイジェストを求めます。
 * [in]
 *	digest		SHA-1ダイジェストを格納するバッテァ。(出力)
 *	data		バイナリデータ。(入力)
 *	len		バイナリデータのバイト数。(>=0)
 * [out]
 *	digest		SHA-1ダイジェストを格納します。
 * [note]
 *	* 以下の資料を参考にしました。
 *	  「SHA-1」(US Secure Hash Algorithm 1 (SHA1))
 *	   (URL: http://www.ipa.go.jp/security/rfc/RFC3174JA.html)
 *	- 本関数は、上記資料内の「6.2 方法 2」に従って、実装したものです。
 *	  本関数の実装は、以下の条件で簡略化を行ないました。
 *	  ・実行環境のバイトオーダーが、リトルエンディアンであるものと決め打ちました。
 *	  ・データストリームに対して繰り返し呼び出すのでなく、
 *	    メモリ上のデータブロックに対して一回の呼び出しで求める用途に限定しました。
 */
void sha1_digest(unsigned char digest[/*20*/], const void* data, int len);

/****************************************************************************
 *	RC4
 ****************************************************************************/

typedef struct _RC4 {
	unsigned char s[256];
	unsigned char i;
	unsigned char j;
} RC4;

/* RC4鍵ストリームをセットアップします。
 * [in]
 *	rc4		初期化するRC4構造体へのポインタ。
 *	_key		RC4鍵。
 *	keylen		RC4鍵のバイト数。
 */
void rc4_init(RC4* rc4, const void* _key/*[keylen]*/, int keylen);

/* データを暗号化、または、復号化します。
 * [in]
 *	rc4		初期化済みのRC4構造体へのポインタ。
 *	_dst		暗号化、または、復号化したデータを格納するバッファ。
 *	_src		暗号化、または、復号化するデータ。
 *	len		データのバイト数。
 * [note]
 *	* _dstと_srcに同じアドレスを指定しても構いません。
 *	  その場合は、元のデータを上書きして、暗号化、または、復号化したデータを格納します。
 */
void rc4_encrypt_decrypt(RC4* rc4, void* _dst/*[len]*/, const void* _src/*[len]*/, int len);
#define rc4_encrypt rc4_encrypt_decrypt
#define rc4_decrypt rc4_encrypt_decrypt

#endif /*__CLIP_CODE_H__*/
