소인수분해
최근 수정 시각: (5년 전)
1. 개요 [편집]
1.1. 온라인 사이트 [편집]
factordb - 이름 그대로 소인수분해 방법이 알려진 수들의 데이터베이스를 제공한다. 모르는 수의 소인수분해 방법이 궁금할 때 참조하면 좋은 자료.
울프람알파에서도 prime factorization 과 함께 숫자를 넣어주면 소인수분해 결과를 보여준다. 간단히 'factor 숫자' 로도 된다.
11111111111111111의 소인수분해
울프람알파에서도 prime factorization 과 함께 숫자를 넣어주면 소인수분해 결과를 보여준다. 간단히 'factor 숫자' 로도 된다.
11111111111111111의 소인수분해
2. 소인수분해를 하는 방법 [편집]
정수 에 대해서,
3의 배수: 각 자릿수의 합이 3의 배수. 4의 배수: 맨 뒤 두 자리가 00 또는 4의 배수. 5의 배수: 끝자리가 0이나 5. 6의 배수: 이 2의 배수이면서 3의 배수. 8의 배수: 맨 뒤 세 자리가 000 또는 8의 배수. 9의 배수: 각 자릿수의 합이 9의 배수. 10의 배수: 끝자리가 0. 15의 배수: 이 5의 배수이면서 3의 배수. 25의 배수: 맨 뒤 두 자리가 00 또는 25의 배수(25, 50, 75) 12의 배수: 이 3의 배수이면서 4의 배수. 20의 배수: 이 4의 배수이면서 5의 배수. 30의 배수: 이 5의 배수이면서 6의 배수. 48의 배수: 이 3의 배수이면서 16의 배수. 72의 배수: 이 8의 배수이면서 9의 배수.
또는 아래 정리를 사용할 수도 있다.
증명은 아래와 같다.
을 합성수라 하자. 그러면 이다. 만약 가 둘 다 보다 크다면, 이 되어 모순이다. 따라서 중 적어도 하나는 보다 같거나 작다.
이 정리에 의해 어떤 큰 수를 소인수분해 할 때, 그 수의 제곱근 보다 큰 수로 나눌 필요는 없다는 사실을 알 수 있다. 이는 노가다를 통해 소인수분해를 하는 시간을 크게 단축시켜 준다.
2.1. 알고리즘 [편집]
프로그래밍으로 소인수를 구할 때는 위와 같은 자질구레한 규칙을 따질 필요 없이, 주어진 숫자 n의 소인수를 구한다고 할 경우 아래와 같은 순서로 진행하면 된다.
- 1. i=2로 시작하여 i++ 하면서 n%i == 0 인지 체크한다.
- 2. n%i==0이 성립하는 경우 i를 소인수로 등록한 후 n은 i로 나눈 값을 저장하고 i는 i++ 하지 않고 i부터 다시 시작하도록 한다.
- 3. n이 1이 될 때까지 위 과정을 반복한다.
어차피 작은 소수에서 n%i == 0이 성립하지 못한다면 그보다 큰 합성수는 n%i == 0가 성립하지 못하므로 n%i == 0이 성립하는 첫번째 i는 소수라는 점을 이용한 알고리즘이다.
이 알고리즘으로 소인수를 구하면 천억이 넘는 숫자도 소인수가 순식간에 구해진다.
간단하게 파이썬으로 코딩 해보면 다음과 같다.
다만 위의 프로그램은 프로그래밍을 익히는 용도로는 유용할수 있으나, 실제 소인수분해 용으로 쓰기에는 적합하지 않다. 실제로 컴퓨터로 다루는 수는 1000억은 '겨우'라는 소리가 나올만큼 큰 수를 다룰 필요가 있기 때문이다.
가장 쉬운 방법은 다른 프로그램을 이용해서 미리 소수 테이블을 작성해 두고, 이를 활용하는 것이다. 예를 들어 216 보다 작은 소수는 6542개인데, 이를 미리 배열에 저장해 두면, 42억 (=232 ) 보다 작은 수는 겨우 6542번 나누어 보기만 하면 소수인지 판정하거나, 1개 이상의 소인수를 구할 수 있다. 232 보다 작은 소수는 모두 약 2억개(203,280,221 개) 인데, 이를 미리 구해서 적절한 DB 에 저장해 두면 약 1000경 (= 264 = 18,446,744,073,709,551,616) 보다 작은 수의 소인수 분해를 쉽게 할 수 있다.
20 자리 정도 되는 이정도 수면 큰 수라고 생각할 수 있지만, RSA 암호화같은 암호학에서 기본 수백자리 수를 다뤄야 한다. RSA 넘버를 보면 가장 작은 것이 100자리 부터 시작하는데, 그마저 250자리 수 까지는 모두 소인수분해되었다. 가장 큰 RSA-2048 은 무려 617자리 수이다. 수의 단위 중 이름이 붙은 최고 단위인 구골이 101자리 수라는 것을 생각해보면, RSA 암호화에서 다루는 수는 사람에게는 어마어마하게 큰 수이다.
밑과 지수를 구하는 기본적인 파이썬 함수는 https://futureengineer.tistory.com/49?category=1181513 에 설명되어있다.
이 알고리즘으로 소인수를 구하면 천억이 넘는 숫자도 소인수가 순식간에 구해진다.
간단하게 파이썬으로 코딩 해보면 다음과 같다.
# -*- coding: utf-8 -*-
import os
import sys
def find_prime(input_num):
if input_num <= 2:
return [input_num,]
for idx in range(2,input_num):
if input_num % idx == 0:
ret_list = []
val_a = find_prime(idx)
val_b = find_prime(int(input_num/idx))
ret_list = val_a + val_b
return ret_list
return [input_num,]
def main():
try:
input_num = int(sys.argv[1])
except:
print("usage: python main.py <number>")
print(" ex> python main.py 12345")
quit()
prime_list = find_prime(input_num)
check_num = 1
for prime_at in prime_list:
check_num *= prime_at
print("[%s] input_num=%d, check_num=%d" % (input_num == check_num, input_num, check_num))
print("%s" % prime_list)
main()다만 위의 프로그램은 프로그래밍을 익히는 용도로는 유용할수 있으나, 실제 소인수분해 용으로 쓰기에는 적합하지 않다. 실제로 컴퓨터로 다루는 수는 1000억은 '겨우'라는 소리가 나올만큼 큰 수를 다룰 필요가 있기 때문이다.
가장 쉬운 방법은 다른 프로그램을 이용해서 미리 소수 테이블을 작성해 두고, 이를 활용하는 것이다. 예를 들어 216 보다 작은 소수는 6542개인데, 이를 미리 배열에 저장해 두면, 42억 (=232 ) 보다 작은 수는 겨우 6542번 나누어 보기만 하면 소수인지 판정하거나, 1개 이상의 소인수를 구할 수 있다. 232 보다 작은 소수는 모두 약 2억개(203,280,221 개) 인데, 이를 미리 구해서 적절한 DB 에 저장해 두면 약 1000경 (= 264 = 18,446,744,073,709,551,616) 보다 작은 수의 소인수 분해를 쉽게 할 수 있다.
20 자리 정도 되는 이정도 수면 큰 수라고 생각할 수 있지만, RSA 암호화같은 암호학에서 기본 수백자리 수를 다뤄야 한다. RSA 넘버를 보면 가장 작은 것이 100자리 부터 시작하는데, 그마저 250자리 수 까지는 모두 소인수분해되었다. 가장 큰 RSA-2048 은 무려 617자리 수이다. 수의 단위 중 이름이 붙은 최고 단위인 구골이 101자리 수라는 것을 생각해보면, RSA 암호화에서 다루는 수는 사람에게는 어마어마하게 큰 수이다.
밑과 지수를 구하는 기본적인 파이썬 함수는 https://futureengineer.tistory.com/49?category=1181513 에 설명되어있다.
3. 관련 문서 [편집]
[1] 합성수가 아니어도 상관은 없지만 그럼 아무 의미가 없어진다.[2] 짝수.[3] 0도 짝수이다.[4] 123456789를 예시로 들면, 123-456+789=456이 7의 배수가 아니므로 원래 수는 7의 배수가 아니다. 59255924를 예시로 들면, 59-255+924=728이 7의 배수이므로 원래 수는 7의 배수이다.[5] 이 방법은 1001=7*11*13, 999999=33*37*1001 임을 이용한 방법이다. 이 외에도 다른 방법들이 있다.[6] 11의 배수는 다른 방법으로, 만약 홀수 번째 자리(일의 자리, 백의 자리, 만의 자리... 등)와 짝수 번째 자리(십의 자리, 천의 자리, 십만의 자리... 등)의 각각의 합의 차가 0 또는 11의 배수이면 그 수는 11의 배수이다. (예: 11110 → 1+1+0=2, 1+1=2, 2-2=0 → 11의 배수.)[7] 이 방법은 999가 27, 37의 배수인 것을 이용했다.[8] 다른 방법(스펜스의 방법)으로는 27의 경우 일의 자리를 8배 하며, 37의 경우 일의 자리 숫자를 11배 하여 나머지 자리 값에서 뺀다 나머지 자리에서 뺀 값이 27/37의 배수이면 원래 수는 27/37의 배수이다.
라이선스를 별도로 명시하지 않은 문서는 CC BY-NC-SA 2.0 KR에 따라 이용할 수 있습니다.
기여하신 문서의 저작권은 각 기여자에게 있으며, 각 기여자는 기여하신 부분의 저작권을 갖습니다.
문서의 기여자는 역사 탭에서 확인할 수 있습니다.
접두어의 N: - 나무위키 사용자, R: - 리그베다 위키의 사용자를 뜻합니다.
자세한 사항은 나무위키에서 동일한 문서의 역사를 참고하시기 바랍니다.