ふと必要になったので作ってみました。
#region AdicNumber Method
///*********************************************
/// <summary>
/// p 進数に変換した値を取得します</summary>
/// <param name="codeList">
/// 1桁で表現できる一意な文字の列を2文字以上で指定します。
/// 最も左の文字が 0 に、1文字右に移動するごとに +1 の値を表す文字になります。
/// 例えば16進法なら、"0123456789ACDEF" のように指定して下さい。</param>
/// <param name="value">
/// 変換する元となるゼロ以上の数値を指定します。</param>
/// <returns>
/// 変換した結果です。
/// 10進法以下であっても常に文字列型を戻します</returns>
/// <remarks>
/// codeList に1文字以下の文字列を指定した場合は、常に空の文字列を返します。</remarks>
///*********************************************
static public string AdicNumber(string codeList, long value) {
// 引数チェック
if (value < 0) {
throw new ArgumentException("ゼロ以上の数値のみ指定できます。", "value");
}
int p = codeList.Length; // codeList の長さ = (p 進法)になる。
if (p < 2) {
throw new ArgumentException("2文字以上指定して下さい。", "codeList");
}
for (int i = 0; i < codeList.Length - 1; ++i) {
for (int j = i + 1; j < codeList.Length; ++j) {
if (codeList[i].Equals(codeList[j])) {
throw new ArgumentException("同じ文字が含まれています。", "codeList");
}
}
}
// 戻り値を格納するための List オブジェクトを生成。
System.Collections.Generic.List<string> ret;
ret = new System.Collections.Generic.List<string>();
do {
int remain = (int)(value % p); // (基数 / p) の剰余を求める。
ret.Add(codeList[remain].ToString()); // その桁の文字を追加。
value = (value - remain) / p; // 絶対に割り切れる。この値を次の基数。
} while (value > 0);
ret.Reverse(); // 先頭の要素の位が一番低くなっているため逆順にする。
return String.Join("", ret.ToArray()); // 連結した文字列を返す。
}
#endregion
0~1024 を
16進数
で取得する場合は、以下のように使います。
static void Main() {
for (int i = 0; i <= 1024; ++i) {
System.Diagnostics.Debug.WriteLine(
i.ToString() + ":" + AdicNumber("0123456789ABCDEF", i)
);
}
}
元は、自動パスワード生成とか、コード番号生成に利用しようと思ったんですが、
AdicNumber("0123456", 値) これで7進数。
AdicNumber("わんくま同盟",値) こうすると6進数を「わんくま同盟」で表現w
などと、いろいろできるなぁ。