JS 문자열 암호화 알고리즘

5578 단어 algorithmsjavascript
이번 주에 나는 문자열을 암호화하는 것과 관련된 기술적 도전에 부딪혔다.나는 메모리에서 추출했지만 작업은 대체로 다음과 같다. 문자열 하나, r값 하나, c값을 정하고 문자열을 하나의 격자로 나누어 r문자와 c문자를 측정하기 위해 암호화한다.그리고 문자열을 위에서 아래로 읽도록 변환합니다.문자열은 항상 길이를 측정하는 r*c로 공백을 문자열 계수로 바꿉니다.
누군가가 나에게 이 알고리즘에 관한 테스트 용례를 주었다. 나는 이미 잃어버렸지만, 시범을 보이기 위해 나는 자신의 테스트 용례를 만들었다.이 메시지는 25글자입니다. r와 c값은 모두 5와 같습니다.
설명에 따라 이 문자열을 다음과 같은 형식으로 변환하고자 합니다.
이것 괜찮아요?
마이사
통용 전기
섭씨 25도
하라크
다음과 같은 문자열을 제공합니다.
“Tmg hhee2ais 5rssi a ascc”
나의 방법은 합리적이지만, 최종 코드는 서투르다.그래서 나는 너희들에게 내가 그것을 어떻게 처리하고 재구성하는지 알려주고 싶다.
설명에 따르면, 가장 좋은 방법은 문자열을 r행과 c열을 측정하는 행렬로 처리한 다음, 이 행렬을 문자열로 바꾸어 한 열씩 아래로 이동하는 것이다.
나의 첫 번째 단계는 세 개의 매개 변수 (duh) function encrypString(message, r, c) 를 가진 함수를 만들고 행렬 let matrix = [] 을 설명한 다음 문자열을 하나의 그룹 let msgArr = message.split(‘’) 으로 나누는 것이다.간단하다
다음 단계는 그룹을 채우는 것입니다.이를 위해while 순환에서 for 순환을 만듭니다.for 순환의 매번 교체에 새 문자가 빈 그룹에 추가됩니다. 그룹의 길이 c - 1, 즉 함수가 제시한 행렬의 끝열 (이 예에서 5) 에 도달하면 이 그룹은 정지됩니다.for 순환이 끝났을 때, 이 새 하위 그룹은 행렬에 밀어 넣습니다.이 순환은 그룹이 비어 있을 때까지 msgArr 변수를 파괴합니다.
  while(msgArr.length > 0){
    let newArr = [];
    for(let i = 0; i < c; i++){
      let newChar = msgArr.splice(0, 1)
      newArr.push(newChar)
    }
    matrix.push(newArr.flat())
  }
물론 이것은 결코 가장 좋은 해결 방안이 아니다.우리는 이따가 더 좋은 선택으로 돌아갈 것이다. 그것은 그리 무겁지 않다.그러나 현재로서는 우리가 필요로 하는 행렬이 생길 것이다.
내 처리 과정에서 다음 단계는 반환값 (우리의 답안) let str = ‘’ 을 생성하고, 열에 따라 그룹을 조작하면 암호화된 문자열을 얻을 수 있는 빈 문자열을 만드는 것이다.나는 for 순환에서 for 순환을 실행하고 문자의 문자열을 다시 조작하는 매우 서투른 방식을 선택했다.
  for (let i = 0; i < c; i++){
    for (let j = 0; j < r; j++){
      str += matrix[j][i]
    }
  }
나는 여기서 중요한 것이 I와 j값을 어떻게 설정하는지 알아차릴 것이다.외부 for 순환은 c값(즉 열)에 따라 실행되고 내부 순환은 줄 크기(r)에 따라 실행됩니다.내부 순환이 끝날 때마다, 이것은 우리가 줄마다 n열을 비운 후에 다음 줄로 들어갈 수 있다는 것을 의미한다.그것은 우리가 필요로 하는 일을 완성하고 목적지에 도달할 수 있도록 도와주었지만, 결코 가장 아름다운 것은 아니다.
이 본문을 다 읽은 후에 나는 내가 더 잘할 수 있다는 것을 안다.이런 순환은 너무 많은 시간을 차지한다.우선 우리의 초기 순환을 보고 for 순환 중의while 순환을 사용하여 행렬을 만듭니다.
나는 두 가지 일을 깨달았다.우선, 나는 원시 문자열을 새 변수에 저장해서 추가 메모리 공간을 차지할 필요가 없다.나는 메시지 = 메시지를 간단하게 설명할 수 있다.분리(")안녕히 계세요msgArr 변수.그 다음으로 나는 순환을 완전히 포기하지 않았지만, 나는 한 번에 하나의 문자를 형성하는 것이 아니라, 맞춤법 (여전히 파괴적인 방식으로 수조를 조종하는 것) 을 사용하여 한 번에 하나의 행렬을 형성하는 방법을 찾았다.
  for(let i = 0; i < c; i++){
      matrix.push(message.splice(0, c))
  }
여기에서 발생하는 일은 메시지 그룹이 처음부터 c 문자로 연결되어 메시지 그룹을 파괴적으로 조종하고, 길이가 c인 새로운 그룹을 생성해서 우리의 행렬로 밀어넣는 것이다.또한 splice는 하나의 그룹을 생성하기 때문에 순환마다 빈 그룹을 설명할 필요가 없습니다.이것은 문자마다 줄을 한 번씩 추가하는 대신 c회만 순환할 수 있도록 합니다. (예시에서 for 순환의 문자열은 25회,while 순환은 5회 순환합니다. 이것은 곧 길어집니다.)
이것은 좋은 진전이다.하지만 우리는 더 잘할 수 있다.다시 한 번, 문자열을 조작하기 위해 쌍for 순환이 있습니다.필요 없어요.하나의 순환은 같은 목표를 실현할 수 있다.우리는 한 번에 한 문자를 조작할 필요가 없고, 분석 함수와 맵 함수를 사용하여 한 번에 한 열을 조작할 수 있다.
let encoded = []
while (matrix.length > 0){
    encoded.push(...matrix.map(subArr => subArr.shift()))
}
재구성은 우리가 행렬을 전송한 후에 모든 하위 진열에서 새 진열을 비추도록 허용한다.시프트를 호출함으로써, 우리는 모든 하위 그룹에서 첫 번째 값을 파괴적으로 조종합니다.전반적으로 말하면, 이것은 우리에게 일렬 행렬과 모든 순환을 주었다.우리가 두 개의 for 순환으로 실현한 것은 문자별로 실행되고, 지금은 열별로 실행되고 있다.괜찮다
빈 문자열을 만들지 않고 빈 문자열을 빈 문자열로 보내는 것을 선택했습니다. 이것은 반환값에서 호출해야 합니다. .join(‘’)나는 join도 매핑 그룹에서 호출할 수 있다고 생각한다. 우리는 처음처럼 문자열str += ...으로 추정할 수 있다.
이전 버전부터 비교해 보겠습니다.
function encryptString(message, r, c){
  let matrix = []
  let msgArr = message.split('')
  while(msgArr.length > 0){
    let newArr = [];
    for(let i = 0; i < c; i++){
      let newChar = msgArr.splice(0, 1)
      newArr.push(newChar)
    }
    matrix.push(newArr.flat())
  }
  message = message.split('')
  for(let i = 0; i < c; i++){
      let newArr = []
      newArr.push(message.splice(0, c))
      matrix.push(newArr)
  }
  let str = ''
  for (let i = 0; i < c; i++){
    for (let j = 0; j < r; j++){
      str += matrix[j][i]
    }
  }
  console.log(str)
  return str
}
새 버전:
function encryptString(message, r, c){
  let matrix = []
  message = message.split('')
  for(let i = 0; i < c; i++){
      matrix.push(message.splice(0, c))
  }
  let word = []
  while(matrix[0].length > 0){
    word.push(...matrix.map(subArr => subArr.shift()))
  }
  return word.join('')
}
이것은 함수의 길이와 운행 시간을 크게 단축시켰고, 나는 최종적인 가독성도 크게 높아졌다고 생각한다.괜찮다만약 내가 실시간 인코딩 연습에서 이 점을 할 수 있다면 좋겠다.
9월 21일 업데이트
계속 개선하려고 노력했습니다. 저는 이 알고리즘을 연구했고 패턴 식별이 있으면 문자열 암호화를 실행하는 더 좋은 방법이 있을 수 있다는 것을 깨달았습니다.나는 우리가 c변수를 효과적으로 무시할 수 있다는 것을 깨달았다. 단지 한 줄 한 줄 값을 수집하기만 하면 된다.상상 r=5.우리는 이 문자열이 5의 배수라는 것을 알고 있기 때문에 5분의 1의 값만 수집하면 문자열의 첫 부분을 구성할 수 있다.이러한 값은 열 [0]의 값이 됩니다.우리는 문자열의 두 번째 부분을 추가해야 한다. (이것은 열[1]이어야 한다. 이것은 색인 r-1의 모든 문자열이 될 것이다.계수기와while 순환이 증가함에 따라 이런 논리는 더욱 쉽게 추적될 수 있다.
이 논리는 for 순환에 저장되어 있으며, 모든 인덱스 값을 검사하거나, 문자열을 필터하고, 특정 문자의 인덱스를 r가 그 열에 있는 것과 같은 여수로 나누는지 검사할 수 있습니다.x는 열 번호에 대응하고 다음과 같다. message.indexOf(char) % r === x.다음 보다 효율적인 함수에서 이 모든 것을 볼 수 있습니다.
function encryptString(message, r, c){
  message = message.split('')
  let newStr = ''
  let x = 0
  while(x < r){
    // for every turn of the loop on x, add the character at the value r - x (x corresponding to the rows)
    newStr += message.filter(char => message.indexOf(char) % r === x).join('')
    x++
  }
  return newStr
}

좋은 웹페이지 즐겨찾기