문제

저는 사용자가 전화를 걸고 휴대폰 키패드를 사용하여 확인 번호를 입력해야 하는 애플리케이션을 개발 중입니다.

입력한 숫자가 올바른지 여부를 감지하고 싶습니다.전화 시스템은 유효한 번호 목록에 액세스할 수 없지만 대신 알고리즘(예: 신용 카드 번호)을 기준으로 번호를 확인합니다.

다음은 몇 가지 요구 사항입니다.

  • 유효한 무작위 코드를 입력하기 어려울 것 같습니다
  • 오타(숫자의 전치, 잘못된 숫자)를 하면 유효한 코드를 얻기 어려울 것입니다.
  • 합리적인 수의 가능한 조합이 있어야 합니다(예: 1M).
  • 사용자의 오류를 방지하려면 코드가 최대한 짧아야 합니다.

이러한 요구 사항이 주어지면 그러한 숫자를 어떻게 생성합니까?

편집하다 :

@하케드:사용자가 휴대폰으로 코드를 입력하기 때문에 코드는 숫자여야 합니다.

@맷 b:첫 번째 단계에서는 코드가 웹 페이지에 표시되고, 두 번째 단계에서는 코드를 호출하여 입력하는 것입니다.사용자의 전화번호를 모릅니다.

후속 조치:여러 알고리즘을 찾았습니다. 확인하다 숫자의 유효성(이 흥미로운 Google 코드 프로젝트를 참조하세요. 숫자 확인).

도움이 되었습니까?

해결책

좀 조사한 후에, 나는 다음과 같이 갈 것이라고 생각합니다. ISO 7064 모드 97,10 공식.IBAN(국제 은행 계좌 번호)을 검증하는 데 사용되므로 꽤 견고해 보입니다.

공식은 매우 간단합니다.

  1. 번호를 선택하세요. 123456
  2. 2자리 체크섬을 얻으려면 다음 공식을 적용하십시오. mod(98 - mod(number * 100, 97), 97) => 76
  3. 코드를 얻기 위해 번호와 체크섬을 연결 => 12345676
  4. 코드를 확인하려면 다음을 확인하세요. mod(code, 97) == 1

시험 :

  • mod(12345676, 97) = 1 => 좋다
  • mod(21345676, 97) = 50 => 나쁘다!
  • mod(12345678, 97) = 10 => 나쁘다!

분명히 이 알고리즘은 대부분의 오류를 포착합니다.

또 다른 흥미로운 옵션은 Verhoeff 알고리즘.검증 숫자가 하나뿐이며 구현하기가 더 어렵습니다(위의 간단한 공식과 비교).

다른 팁

1M 조합의 경우 6자리 숫자가 필요합니다.실수로 유효한 코드가 발생하지 않도록 하려면 무작위 코드가 작동할 확률이 1/1000인 9자리 숫자를 제안합니다.또한 다른 숫자(총 10개)를 사용하여 다음을 수행하는 것이 좋습니다. 무결성 검사.배포 패턴에 관해서는 무작위로 충분하며 검사 숫자는 단일 오류로 인해 올바른 코드가 발생하지 않도록 보장합니다.

편집하다: 아무래도 제가 귀하의 요청을 완전히 읽지 못한 것 같습니다.신용카드 번호를 사용하여 해시를 수행할 수 있습니다(MD5 또는 SHA1 또는 이와 유사한 것).그런 다음 적절한 위치(예: 9자)에서 자르고 기본 10으로 변환합니다.그런 다음 확인 숫자를 추가하면 이는 귀하의 목적에 어느 정도 작동할 것입니다.

코드를 분할하고 싶습니다.그 중 일부는 나머지 코드의 16비트 CRC여야 합니다.

원하는 것이 확인 번호뿐이라면 시퀀스 번호를 사용하세요(단일 생성 지점이 있다고 가정).그렇게 하면 중복이 발생하지 않는다는 것을 알 수 있습니다.

그런 다음 해당 시퀀스 번호의 CRC-16과 일부 개인 키를 시퀀스 앞에 붙입니다.비공개로 유지하는 한 비공개 키로 무엇이든 사용할 수 있습니다.뭔가 큰 일을 하세요. 적어도 GUID, 하지만 다음의 텍스트일 수도 있습니다. 구텐베르크 프로젝트의 전쟁과 평화.비밀스럽고 지속적이어야합니다.개인 키가 있으면 사람들이 키를 위조할 수 없지만 16비트 CR을 사용하면 키를 더 쉽게 해독할 수 있습니다.

유효성을 검사하려면 번호를 두 부분으로 분할한 다음 시퀀스 번호와 개인 키의 CRC-16을 가져옵니다.

순차 부분을 더 모호하게 하려면 CRC를 두 부분으로 분할하십시오.시퀀스 앞쪽에 3자리, 뒤쪽에 2자리를 입력합니다(CRC 길이가 일정하도록 제로 패드 사용).

이 방법을 사용하면 더 작은 키로도 시작할 수 있습니다.처음 10개의 키는 6자리입니다.

꼭 숫자로만 이루어져야 하나요?1에서 1M 사이의 임의의 숫자를 생성할 수 있습니다(그래도 더 높은 값을 제안합니다). Base32로 인코딩.다음으로 해야 할 일은 해당 값을 해시하고(비밀 솔트 값을 사용하여) 해시를 base32로 인코딩하는 것입니다.그런 다음 대시로 구분하여 두 문자열을 함께 추가합니다.

이렇게 하면 들어오는 코드를 알고리즘적으로 확인할 수 있습니다.코드의 왼쪽을 가져와서 비밀 솔트를 사용하여 해시하고 해당 값을 코드의 오른쪽과 비교하면 됩니다.

  • 합리적인 수의 가능한 조합이 있어야 합니다(예: 1M).
  • 사용자의 오류를 방지하려면 코드가 최대한 짧아야 합니다.

글쎄, 만약 당신이 적어도 백만 개의 조합을 갖고 싶다면 적어도 6자리 숫자가 필요합니다.그 정도면 충분해요?

인증 코드를 생성할 때 발신자의 전화번호에 액세스할 수 있습니까?

그렇다면 발신자의 전화번호를 사용하고 일종의 해싱 기능을 통해 이를 실행하여 1단계에서 발신자에게 제공한 확인 코드가 2단계에서 입력한 것과 동일하다는 것을 보장할 수 있습니다. 친구의 인증 코드를 사용하지 않았거나 단지 매우 운이 좋은 추측을 한 것일 뿐입니다.)

해싱에 관해서는 10자리 숫자를 사용하여 10자리 미만의 해시 결과가 나오는 것이 가능한지 잘 모르겠습니다(어느 정도의 충돌을 감수해야 할 것 같습니다). 이는 사용자가 자신이 누구인지 확인하는 데 도움이 됩니다.

물론 1단계에서 사용한 전화번호가 2단계에서 전화를 거는 전화번호와 다른 경우에는 작동하지 않습니다.

사용자가 어떤 키를 눌렀는지 감지하는 방법을 이미 알고 있다고 가정하면 이 작업은 합리적으로 쉽게 수행할 수 있습니다.보안 세계에는 "일회용" 비밀번호라는 개념이 있습니다.이것은 때때로 "일회용 비밀번호"라고도합니다. 일반적으로 이들은 (쉽게 입력 가능한) ASCII 값으로 제한됩니다.따라서 [a-zA-z0-9] 및 쉽게 입력할 수 있는 여러 기호가 있습니다.쉼표, 마침표, 세미콜론, 괄호 등이 있습니다.하지만 귀하의 경우에는 범위를 [0-9]로 제한하고 * 및 #을 포함할 수도 있습니다.

이러한 일회용 코드가 어떻게 적절하게 생성(또는 작동)되는지에 대한 모든 기술적 세부 사항을 설명할 수는 없습니다.그 뒤에는 몇 가지 중간 수학이 있는데, 내가 직접 검토하지 않고 정육점으로 삼을 것입니다.일회용 비밀번호 스트림을 생성하기 위해 알고리즘을 사용한다고 말하면 충분합니다.이전 코드를 아무리 많이 알고 있더라도 다음 코드는 추측할 수 없습니다!귀하의 경우 목록에 있는 각 비밀번호를 사용자의 임의 코드로 사용하면 됩니다.

구현 세부 사항을 직접 설명하는 데 실패하는 대신 직접 읽을 수 있는 9페이지 분량의 기사를 안내해 드리겠습니다. https://www.grc.com/ppp.htm

알고리즘을 통해 코드가 유효한지 신속하게 확인해야 한다는 암묵적인 요구 사항이 있는 것 같습니다.이것은 단순히 일회용 패드 번호 목록을 나눠주는 것을 배제합니다.

과거에 사람들이 이 작업을 수행한 방법에는 여러 가지가 있습니다.

  1. 공개키와 개인키를 만듭니다.개인 키를 사용하여 0-999,999의 숫자를 인코딩하고 결과를 전달합니다.결과가 더 긴 버전으로 나오도록 하려면 임의의 숫자를 입력해야 하며 결과를 기본 64에서 기본 10으로 변환해야 합니다.숫자가 입력되면 다시 base64로 변환하고 개인 키를 적용한 후 해당 숫자가 1,000,000 미만인지 확인합니다(난수는 폐기).
  2. 사용 가역적 해시 함수
  3. 특정 값에 시드된 PRN의 처음 백만 개의 숫자를 사용합니다."검사" 기능은 시드를 얻을 수 있으며 다음 백만 개의 값이 좋은지 알 수 있습니다.매번 생성하고 코드가 수신될 때 하나씩 확인하거나 프로그램 시작 시 모든 것을 테이블에 저장하고 정렬한 다음 이진 검색(최대 비교)을 사용할 수 있습니다. 왜냐하면 백만 개의 정수는 전체가 아니기 때문입니다. 공간의.

다른 옵션도 많이 있지만 이는 일반적이고 구현하기 쉽습니다.

-아담

당신은 다음에 연결했습니다 숫자 확인 프로젝트를 진행하고 "인코딩" 기능을 사용하는 것이 좋은 해결책인 것 같습니다.그것은 말한다:

'잘못된' 데이터(예:숫자가 아닌)가 전달되는 반면 확인은 true 또는 false만 반환합니다.여기서의 아이디어는 인코딩이 일반적으로 '신뢰할 수 있는' 내부 소스(예: 데이터베이스 키)에서 데이터를 가져오므로 잘못된 데이터가 전달되는 경우는 매우 일반적이며 실제로는 예외라는 것입니다.

따라서 인코딩 기능에 데이터베이스 키(예: 5자리)를 전달하면 요구 사항에 맞는 숫자를 얻을 수 있는 것처럼 들립니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top