転置式暗号
転置式暗号とは
平文の順番を入れ替える暗号方式を転置式暗号
という。
平文を一定のブロックに分けて、順番を入れ替えていく。ブロックの長さを n とすると平文の文字の数が n の場合数出ない場合は綺麗にブロック分けができない。余ったブロックには何らかの文字を入れパディングする方法やそのままにして順番を入れ替えない方法等がある。
パディングする場合は単純にパティングしてしまうとパティング文字以外の移動位置がバレてしまう可能性があるので注意が必要である。
プログラム
- Python
- C++
- C#
- Rust
- JavaScript
transposition-cipher.py
import random
def generate_transposition_table(size: int):
table = [i for i in range(size)]
random.shuffle(table)
return table
def transposition_cipher(input_text: str, transposition_table: list[int], direction: str = "encryption"):
input_text = input_text.upper()
result = []
size = len(transposition_table)
if direction == "decryption":
temp_table = [0] * size
for i in range(size):
temp_table[transposition_table[i]] = i
transposition_table = temp_table
for i in range(0, len(input_text) - size+1, size):
temp_text = ""
for j in range(size):
temp_text += input_text[i + transposition_table[j]]
result.append(temp_text)
if len(input_text) % size != 0:
result.append(
input_text[-(len(input_text) % size):]
)
return "".join(result)
transposition-cipher.cpp
vector<int> generateTranspositionTable(int size)
{
vector<int> table;
for (int i = 0; i < size; ++i)
table.push_back(i);
std::random_device get_rand_dev;
std::mt19937_64 get_rand_mt(get_rand_dev());
std::shuffle(table.begin(), table.end(), get_rand_mt);
return table;
}
string transpositionCipher(string inputText, vector<int> transpositionTable, string direction = "encryption")
{
transform(inputText.begin(), inputText.end(), inputText.begin(), ::toupper);
vector<string> result;
int size = transpositionTable.size();
if (direction == "decryption")
{
vector<int> tempTable(size, 0);
for (int i = 0; i < size; ++i)
tempTable[transpositionTable[i]] = i;
swap(transpositionTable, tempTable);
}
for (int i = 0; i < inputText.size() - size + 1; i += size)
{
string tempText = "";
for (int j = 0; j < size; ++j)
tempText += inputText[i + transpositionTable[j]];
result.push_back(tempText);
}
if (inputText.size() % size != 0)
{
result.push_back(inputText.substr(inputText.size() - (inputText.size() % size)));
}
std::ostringstream os;
std::copy(result.begin(), result.end(), std::ostream_iterator<std::string>(os));
return os.str();
}
transposition-cipher.cs
static private int[] GenerateTranspositionTable(int size)
{
int[] table = new int[size];
for (int i = 0; i < size; ++i)
{
table[i] = i;
}
return table.OrderBy(i => Guid.NewGuid()).ToArray();
}
static private string TranspositionCipher(
string inputText,
int[] transpositionTable,
string direction = "encryption"
)
{
inputText.ToUpper();
List<StringBuilder> result = new List<StringBuilder>();
int size = transpositionTable.Length;
if (direction == "decryption")
{
int[] tempTable = new int[size];
for (int i = 0; i < size; ++i)
{
tempTable[transpositionTable[i]] = i;
}
(transpositionTable, tempTable) = (tempTable, transpositionTable);
}
for (int i = 0; i < inputText.Length - size + 1; i += size)
{
StringBuilder tempText = new StringBuilder();
for (int j = 0; j < size; ++j)
{
tempText.Append(inputText[i + transpositionTable[j]]);
}
result.Add(tempText);
}
if (inputText.Length % size != 0)
{
result.Add(
new StringBuilder(
inputText.Substring(inputText.Length - (inputText.Length % size))
)
);
}
StringBuilder ret_string = new StringBuilder();
for (int i = 0; i < result.Count; ++i)
{
ret_string.Append(result[i]);
}
return ret_string.ToString();
}