React 中维吉尼亚密码的着色列

问题描述 投票:0回答:1

我在反应中制作了维吉尼亚密码。关于维吉尼亚密码算法,一切都很完美。我只想补充一件事。当我从文本中取出一个字母,从密码中取出一个字母时,我希望板上对应的行和列一一着色。例如:如果密码是cat,文本是rat,首先我要点亮c和r的相应行和列,然后是下一步a和a,然后是t和t。就是这样。

目前我不知道如何使用

useState()
来让每一步的每一列和行都着色。我设法对最后一行和最后一列进行着色,但这不是我想要的。

// import { useState } from 'react';
// import './App.css';

function VigenereCipher() {
  const georgianLetters = 'აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰ';
  const table = Array.from({ length: 33 }, (_, i) =>
    Array.from({ length: 33 }, (_, j) => georgianLetters[(i + j) % 33])
  );
  const [password, setPassword] = React.useState('');
  const [text, setText] = React.useState('');
  const [ciphered, setCiphered] = React.useState('');
  const [row, setRow] = React.useState(null);
  const [col, setCol] = React.useState(null);
  
  const handlePasswordChange = (event) => {
    setPassword(event.target.value);
  };

  const handleTextChange = (event) => {
    setText(event.target.value);
  };

  const handleCipherButtonClick = () => {
    if (!password || !text) {
      setCiphered('');
      alert(`შეავსეთ პაროლის და ტექსტის ველები`);
      return;
    }
  
    let k = 0;
    let cipheredText = '';
  
    for (let i = 0; i < text.length; i++) {
      if (text[i] === ' ') {
        cipheredText += ' ';
      } else {
        const rowIndex = georgianLetters.indexOf(text[i]);
        const colIndex = georgianLetters.indexOf(password[k]);
        if (rowIndex !== -1 && colIndex !== -1) {
          cipheredText += table[rowIndex][colIndex];
          k = (k + 1) % password.length;
        }
      }
    }
  
    setCiphered(cipheredText);
  };

  return (
    <div className="main">
      <table>
        <tbody>
          {georgianLetters.split('').map((letter, i) => (
            <tr key={i} style={i === row ? {backgroundColor: 'red'}: {}}>{georgianLetters.split('').map((innerLetter, j) => (
                <td 
                  key={j} 
                  style={{
                    backgroundColor: i === row && j === col ? 'purple': j === col ? 'red': 'none',
                  }}
                >{table[i][j]}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
      <div className="right-side">
        <div className='pass-text'>
          <label>პაროლი</label>
          <input type="text" value={password} onChange={handlePasswordChange} />
          <label>ტექსტი</label>
          <textarea value={text} onChange={handleTextChange}></textarea>
        </div>

        <button onClick={handleCipherButtonClick}>დაშიფვრა</button>
        <div className="ciphered">
          <textarea readOnly value={ciphered}></textarea>
        </div>
      </div>
    </div>
  );
}

ReactDOM.render(<VigenereCipher/>, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>

javascript reactjs encryption vigenere
1个回答
1
投票

您可以简单化

split()
这两个单词,并使用不同的背景颜色分别渲染每个字符。

const colors = [
    "orange",
    "green",
    "yellow",
    "red",
    "cyan"
]

function TextCompare({ x, y }) {
    const [wordOne, setWordOne] = React.useState(x);
    const [wordTwo, setWordTwo] = React.useState(y);

    return (
        <div>
            <div>
                {wordOne.split("").map((x, i) => <Character index={i} character={x}/>)}
            </div>
            <div>
                {wordTwo.split("").map((x, i) => <Character index={i} character={x}/>)}
            </div>
        </div>
    )
}

function Character({ index, character }) {
    return (<span style={{ backgroundColor: getColor(index) }}>{character ? character : ""}</span>); // you should use character ?? "" but SO does not let me do that here
}

function getColor(index) {
    return colors[index % colors.length];
}

ReactDOM.render(<TextCompare x="caterpillar" y="cat" />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>

要无限期地生成漂亮的颜色,您还可以使用生成器函数。我无法在 StackOverflow 上的 React 代码段中使用 generator function,但你应该能够在你的页面上执行此操作。然后,您只需为每个单词实例化两个生成器:

// generator function
function* generateHslaColor(saturation, lightness, alpha, amount) {
    let huedelta = Math.trunc(360 / amount)
    let i = 0;
    while (true) {
        const hue = huedelta * (i++ % amount);
        yield `hsla(${hue},${saturation}%,${lightness}%,${alpha})`;
    }
}

// generate 20 numbers which repeat after 5 colors
const repeatAfter = 5
// instantiate generator (if you need the same color sequence twice, instantiate two with same parameters)
const colorGenerator = generateHslaColor(50, 100, 1.0, repeatAfter); 
console.log([...new Array(20)].map(x => colorGenerator.next().value));
/* Stackoverflow: show only console */
.as-console-wrapper {
    max-height: 100% !important;
    top: 0;
}

© www.soinside.com 2019 - 2024. All rights reserved.