bashで素数×素数の生成(openssl/factor)

■opensslは16進数で素数を返す。

$ openssl prime "10"
A is not prime

$ openssl prime "13"
D is prime

■opensslを使った1から100までの素数の生成

$ for n in `seq 1 100`;do \
    echo $((0x`openssl prime "$n" | awk '($3!="not"){print $1}'`)) ; \
  done | grep -v "^0\$" | xargs echo
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

■opensslを使った1から100までの素数の自乗の生成

$ for n in `seq 1 100`;do \
    echo $((0x`openssl prime "$n" | awk '($3!="not"){print $1}'`)) ; \
  done | grep -v "^0\$" | awk '{print $1"*"$1}' | bc | xargs echo
4 9 25 49 121 169 289 361 529 841 961 1369 1681 1849 2209 2809 3481 3721 4489 5041 5329 6241 6889 7921 9409

■factorは素因数分解を行う。

$ apropos factor
factor (1)           - 数値を素因数分解して素数の約数を表示...
factor (6)           - factor は素因数分解を行なう, primes は素...
primes (6)           - factor は素因数分解を行なう, primes は素...
XML::SAX::ParserFactory (3pm) - Obtain a SAX parser
XML::SAX::PurePerl::Reader (3pm) - Abstract Reader factory class

■factorを使った1から100までの素数の生成

$ echo `seq 1 100` | factor | awk 'NF==2{print $NF}' | xargs echo -n;echo
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

■factorを使った1から100までの素数の自乗の生成

$ echo `seq 1 100` | factor | awk 'NF==2{print $NF"*"$NF}' | bc | xargs echo
4 9 25 49 121 169 289 361 529 841 961 1369 1681 1849 2209 2809 3481 3721 4489 5041 5329 6241 6889 7921 9409

■factorを使った任意の範囲の素数×素数(素数の自乗の出現頻度は低い)の生成
 擬似乱数の範囲内で取得。

$ for n in `seq 1 100`;do \
    echo $(($RANDOM % 100000)) | factor | awk '(NF==3){print $0}'; \
  done | sort -k 2 -nr | head -10
28891: 167 173
23711: 131 181
12091: 107 113
31679: 79 401
27887: 79 353
20299: 53 383
19639: 41 479
2117: 29 73
703: 19 37
3629: 19 191

■以下のように、素数の自乗が出現しないわけではない。

$ for n in `seq 1 100`;do \
    echo $(($RANDOM % 100000)) | factor | awk '(NF==3){print $0}'; \
  done | awk '($2==$3){print}'
6241: 79 79

■真面目に以下のように、「1万から2万の間」と指定すると結構時間がかかる。

$ for n in `seq 10000 20000`;do echo $n | factor | awk '(NF==3){print $0}';done

■素因数分解するのに、opensslよりfactorの方が速い。