メインコンテンツまでスキップ

多表式暗号

多表式暗号とは

多表式暗号では、平文を n 文字ごとにブロック化し、各ブロック内の文字に対して異なる換字キーを適用する。 これにより、同じ文字が異なるブロック内で異なる方法で暗号化され、解読が難しくなります。

プログラム

polyalphabetic-substitution-cipher.py
import random
def generate_polyalphabetic_substitution_table(size: int):
base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result = []
table = [i for i in base]
for i in range(size):
random.shuffle(table)
result.append("".join(table))
return result


def polyalphabetic_substitution_cipher(input_text: str, transposition_table: list[str], direction: str = "encryption"):
input_text = input_text.upper()
mod = len(transposition_table)
base = ["ABCDEFGHIJKLMNOPQRSTUVWXYZ"] * mod

result = []
if direction == "decryption":
transposition_table, base = base, transposition_table
for i in range(len(input_text)):
result.append(transposition_table[i % mod]
[base[i % mod].index(input_text[i])])
return "".join(result)

動作

ライブエディター
function SimpleSubstitutionCipher(props) {
  // 暗号化 or 復号化する文字列
  const inputText = "APPLE";

  // encryption or decryption
  const direction = "encryption";

  // 変換テーブルの個数
  const size = 3;

  // 以下は特に変更しなくて良い
  const base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  //Fisher-Yatesシャッフルアルゴリズム
  function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; --i) {
      const j = Math.floor(Math.random() * (i + 1));
      // 要素の交換
      [array[i], array[j]] = [array[j], array[i]];
    }
  }

  function generatePolyalphabeticSubstitutionTable(size) {
    let result = [];
    for (let i = 0; i < size; ++i) {
      const chars = base.split("");
      shuffleArray(chars);
      result.push(chars);
    }
    return result;
  }
  function polyalphabeticSubstitutionCipher(
    inputText,
    transpositionTable,
    direction = "encryption"
  ) {
    inputText = inputText.toUpperCase();
    const mod = transpositionTable.length;
    let retText = "";
    let _base = new Array(mod).fill(base);
    let _transpositionTable = transpositionTable;
    if (direction == "decryption") {
      _transpositionTable = new Array(mod).fill(base);
      _base = transpositionTable;
    }

    for (let i = 0; i < inputText.length; ++i) {
      retText +=
        _transpositionTable[i % mod][_base[i % mod].indexOf(inputText[i])];
    }
    return retText;
  }

  // React
  const [table, setTable] = useState(undefined);
  const [cipher, setCipher] = useState(undefined);

  // tableが生成された後に暗号化を行う
  useEffect(() => {
    if (!table) return;
    const cipher = polyalphabeticSubstitutionCipher(
      inputText,
      table,
      "encryption"
    );
    setCipher(cipher);
  }, [table]);
  // 読み込み時に一度だけ呼び出す
  useEffect(() => {
    // 読み込みできてから呼びだす
    setTable(generatePolyalphabeticSubstitutionTable(size));
  }, []);
  return (
    <>
      <div
        style={{
          display: "flex",
          flexDirection: "row",
          flexWrap: "nowrap",
          alignItems: "flex-start",
          justifyContent: "space-evenly",
        }}
      >
        <div>
          <h3>元の文字列</h3>
          <p>{inputText}</p>
        </div>
        {table === undefined || cipher === undefined ? (
          /* 変換テーブルを生成してるかつ暗号化済みであれば表示 */ <></>
        ) : (
          <>
            <span
              className="mrel"
              style={{ padding: "5px", margin: "auto 0px" }}
            >

            </span>
            <div>
              <h3>暗号化</h3>
              <p>{cipher}</p>
            </div>
            <span
              className="mrel"
              style={{ padding: "5px", margin: "auto 0px" }}
            >

            </span>
            <div>
              <h3>復号化</h3>
              <p style={{ padding: "1px", margin: "2px" }}>
                {polyalphabeticSubstitutionCipher(cipher, table, "decryption")}
              </p>
            </div>
          </>
        )}
      </div>
      <h3>変換テーブル</h3>
      {table === undefined || cipher === undefined ? (
        /* 変換テーブルを生成してるかつ暗号化済みであれば表示 */ <></>
      ) : (
        table.map((val) => {
          return <p>{val}</p>;
        })
      )}
    </>
  );
}
結果
Loading...