회사에서 랜덤패스워드를 생성해보고 싶어서 윈도우 배치파일로 시도해보다 포기하고 결국 자바로 짜봤습니다. 자바라 해봐야 신입사원 교육받을 때 2주간 배운게 전부라, 코딩 수준은 기초를 벗어나지 못합니다만 그래도 복잡한 패스워드를 생성해야 할 때 쓸만하지 않을까 싶어 올려봅니다. 아스키 테이블 33번부터 126번까지 랜덤하게 10자리씩 생성해줍니다.

개발자 분들 좋은 아이디어 있다면 댓글 조언 언제든지 환영입니다. ^^ 

public class Password {
    public static void main(String[] args) {
        int[] asciiNum = new int[10];
        for (int i = 0; i < 20; i++) {
            for (int j = 0; j < asciiNum.length; j++) {
                int ranNum = -1;
                ranNum = (int) ((Math.random() * 94) + 33);
                asciiNum[j] = ranNum;
            }
            for (int n : asciiNum) {
                System.out.print((char) n);
            }
            System.out.println();
        }
    }
}


Starbros님 조언을 듣고 반복문을 줄이고 배열도 뺐습니다.
최종 다이어트 코드는 아래와 같습니다.
10자리 랜덤패스워드 20개 생성하는건데, 여기서 더 줄이는건 불가능해 보이네요. 

public class Password {
     public static void main(String[] args) {
         for (int i = 0; i < 200; i++) {
             System.out.print((char)((Math.random() * 94) + 33));
             if (i%10==9) System.out.println();
         }
     }
}
신고
Share
  1. 참글
    2011.05.21 02:20 신고

    예전부터 궁금한게 있었는데, 자바나 C 등에서 Random 함수 (여기서는 Math.random() ) 를 구현하는 알고리즘이 뭔가요?

    혹시나 스누피님은 아실까해서 질문남겨봅니다.

    • BlogIcon snpbox
      2011.05.21 02:29 신고
      수정 및 삭제

      저는 공대생이 아니라서 모르겠네요 ;;

    • BlogIcon 노버
      2011.05.21 04:48 신고
      수정 및 삭제

      난수표를 범위로 나눈 나머지 값을 랜덤값으로 출력합니다.
      때문에 C에서 난수표를 시간별로 따로 생성해서 사용하지 않으면
      수만번 뽑다보면 규칙성이 드러나게 되는 문제점이 있죠.

      최근에 나오는 언어들은 이러한 문제점을 보완하고 있습니다.

  2. 봄봄
    2011.05.21 02:42 신고

    오 저도 일등으로 글 남겨 보는군요. 제가 페이스북으로 로긴해서 댓글 써보려고 했는데 다른 댓글 무시하고 제일 위에 달리는 데다가 프로필사진도 적나라하게 나와서 못쓰겠더라고요ㅠㅋ
    스누피님 원래 프로그래밍 제대로 공부해 보신적이 없는 건가요? 컴퓨터 잘하시는 거 보고 전산을 꽤 공부하셨을 거라고 생각했거든요. 아니면 다른 언어를 많이 공부하셨나요? 하하. 제가 java를 공부한 게 8년 전이라 기억이 하나도 안나고 단지 언어로서 스트럭처만 이해가 되는데요.
    10자리씩 20개의 랜덤 문자열을 생성해주는 건가요?

    for (int n : asciiNum) {System.out.print((char) n);} 그리고 이게 엔터 없이 자동으로 옆으로 쓰는 건가요?
    그렇다면 for (int i = 0; i < 20; i++) { ... } 여기서도 루프 돌면서 엔터 없이 계속 옆으로만 쓰게 되는거 아닌가요? System.out.print()가 정확히 어떻게 작동하는지 기억이 하나도 안나 모르겠습니다. 하하 도움이 안되는군요.

    배치파일 언어는 bcdedit 활용법을 알아내기 위해서 ㅡ 나중에 따로 포스트가 있다는 것을 뒤 늦게 보고 참 안타까워했지만 ㅡ 스누피님이 cmd파일 업로드 해놓은걸 보면서 조금 배운게 전부인데요.
    만약 랜덤함수와 integer로 올림해주는 함수만 있으면 되지 않을까요?
    귀찮지만 94개의 문자를 일일이 매핑만 하면 될텐데요. 물론 integer를 ascii로 매핑해주는 함수가 있으면 당연히 되겠지만요. 하하. 시도는 하셨다니깐 랜덤함수는 있을테고 integer로 올림하는 함수나 방법이야 있을것 같고 ascii로의 매핑도 있을법도 하긴 한데요. :D

    • BlogIcon snpbox
      2011.05.21 13:38 신고
      수정 및 삭제

      네 저는 전공이 사회과학이라 컴퓨터는 배우지 못했습니다. 그냥 궁금한거 생기면 혼자 실험해보거나 검색해보는 식으로 컴퓨터를 익힌거죠.

      10자리 패스워드 20개 생성하는거 맞구요, print는 옆으로 쓰는거 맞는데 println은 개행해줍니다.

      배치에선 아스키로 매핑하는거랑 10개 뽑아서 가로로 쓰는게 쉽지가 않더군요. 일단 배열 개념이 없기 때문에 노가다를 장난 아니게 해야 겨우 만들 것 같습니다.

    • 봄봄
      2011.05.21 23:04 신고
      수정 및 삭제

      연대 공학계열이라길래 공대출신이라고 생각했거든요. :D
      그러게요 지금 보니깐 하나는 .print()고 하나는 .println()이네요.

  3. BlogIcon andu
    2011.05.21 06:38 신고

    확실히 배치의 랜덤변수는 조금 쓰기 애매하죠,,,,

  4. 컴맹
    2011.05.21 07:19 신고

    저는 프로그래밍이라고는 아무것도 모르는 컴맹입니다.
    난수생성 유틸리에 꼭 있었으면 하는 기능이 있어 몇 자 남깁니다.
    혹시 다는 아니더라도 이런 기능을 지원하는 프로그램을 아시는 분은 소개를 부탁드립니다.
    스누피님께서 이렇게 만드시면 참 좋을 것 같습니다.

    제가 원하는 기능은.......

    1. 사용자가 마스터비밀번호와 변수를 입력해 결과값을 출력하는 구조면 좋겠습니다. (hashapass.com처럼요)
    2. 각각의 변수를 따로 입력할 수 있어서 한 번에 여러개의 결과를 얻을 수 있었으면 좋겠습니다.
    3. 결과값의 자릿수를 사용자가 마음대로 정할 수 있었으면 좋겠습니다.
    4. 결과값 출력시 대소문자 구분, 특수문자 허용 여부를 선택할 수 있었으면 좋겠습니다. (입력시에는 모두 허용)
    5. 결과값과 마스터비밀번호로 변수를 역산할 수 있는 기능도 있었으면 좋겠습니다.
    7. 암호화 여부와 상관없이 그 어디에도 입력과 출력값이 기록되지 않았으면 좋겠습니다.
    8. 무설치로 실행할 수 있었으면 좋겠습니다.

    • 봄봄
      2011.05.21 11:05 신고
      수정 및 삭제

      hashhapass.com라는 곳을 처음 봤는데 재밌는 곳이네요.
      1. 이런건 개인 취향에 따라 자기가 엑셀로 만들면 됩니다.
      2. 문자열을 변수로 받고 문자열을 return하는 함수를 만들면 되죠.
      3. 저 홈페이지에서 parameter, master password라고 나눠놓은게 이상하네요. 그냥 variable 1, variable 2라고 생각해도 될 것 같습니다. 어차피 다 똑같은 변수인데요.
      4. 결과값의 자릿수, 대소문자 등등 역시 엑셀로 하기 나름입니다.
      5. 역산이 가능하게 하려면 함수를 1-1 함수(일대일함수, 단사함수, 또 다른 말로 injection)로 만들면되고 역산이 불가능하게 하려면 1-1 함수가 아닌 onto function(우리말로는 별로 안쓰이지만 전사함수, 또 다른 동의어로 surjection)으로 만들면 됩니다. 그런데 역산이 가능하도록 1-1함수를 만드려면 단지 간단하게 만들면 되겠지만 좀 복잡하고 그럴싸한 함수를 만들면서 1-1 함수가 되도록 하려면 좀 어려울 것 같군요.

      1-1함수를 만드는 쉬운예로,
      mid($A$1, i,i+1)이런식으로 변수 문자열을 하나하나 쪼갠 다음에 각각 낱개의 문자를 이미 랜덤으로 매핑해놓은 테이블에 따라 매핑값구하고 그것들을 다시 하나의 문자열로 만들면 되겠지요.
      예로 a -> 4, b -> $, c -> u ... 뭐 이런식으로요. 이렇게 하면 매핑테이블(이게 바로 1-1함수, 여기서 변수는 문자 1개, 함수값도 문자 1개)만 알면 역산이 가능하겠죠. 4는 a였고 $는 b였고 u는 c였다는 식으로요.

      아.. 더 쉽게 하자면 shift한 번 하면 되는 거죠. 변수가 abcd1234였으면 반환값은 bcde2345로요. 복잡한 정도는 역시 자기가 만들기 나름입니다. :)

      hashapass.com도 저런식으로 함수를 이용하는 것인데 저렇게 간단하진 않을 것입니다. 웹페이지를 다운받아보니 sha1.js파일에 함수가 있는 것 같은데 역시 좀 복잡해 보이는군요. 사실 개인 입장에서 복잡할 필요 없는데 간단하면 별로 안 멋지잖아요.

      복잡하게 만드는 이유는 암호를 만드는 함수를 들키지 않기 위해서 이고, 변수를 넣는 규칙을 들키지 않기 위해서이죠.

      예를 들어 인터넷 사이트 주소 첫자와 아이디 첫자와 아이디 길이, 이렇게 세 개를 변수로 갖고, 아까 상기 예처럼 단순 무식하게 직접 1-1 대응만 해주는 테이블만 하나 만들어줘도 변수가 뭐고 테이블이 뭔지만 안들키면 자신의 암호 공식은 들키지 않겠죠.

      :D

  5. BlogIcon 앙꼬없는찐빵
    2011.05.21 12:07 신고

    랜덤 함수는 쓰실때 seed값을 시간으로 주시는건 간단한 센스죠 ^^

    • BlogIcon snpbox
      2011.05.21 13:42 신고
      수정 및 삭제

      자바의 Math.random() 함수는 자동으로 타임시드 사용해서 불규칙 난수를 생성한다고 하더군요. 지난번 로또번호 생성글에 starbros님이 남겨주신 댓글입니다.

    • BlogIcon starbros
      2011.05.25 23:38 신고
      수정 및 삭제

      네 그건 C언어에서나 해당되구요. Java의 Math.random() 클래스는
      ()안에 별도의 조건을 명시하지 않는 이상은 Default로 자동타임시드
      가 적용되고 있습니다. 말그대로 타임시드값을 자동으로 변경시켜
      주기때문에 규칙성에의한 예측이 불가능하다 보시면 됩니다. ミ:^)

  6. 동우
    2011.05.21 20:01 신고

    http://zextor.tistory.com/2669805
    http://kr.blog.yahoo.com/lbdlbd123/1076
    다른 분들이 짠 거립낟 도움 되셨으면 해서 올리네요

  7. BlogIcon KurenoCat
    2011.05.21 23:06 신고

    Shell 스크립트는 한줄로 끝나죠 ㅋ_ㅋ

    #!/bin/bash
    for ((n=0;n<20;n++)); do dd if=/dev/urandom count=1 2> /dev/null | uuencode -m -| sed -ne 2p | cut -c-10; done

  8. BlogIcon 사흑도
    2011.05.22 09:43 신고

    스누피님.. 저 에러가 나는대요..
    \Desktop\test\1.java:1: class Password is public, should b
    e declared in a file named Password.java
    public class Password {
    ^
    1 error
    계속하려면 아무 키나 누르십시오 . . .

  9. 베인
    2011.06.09 10:01 신고

    public class Password {
    public static void main(String[] args) {
    for (int i = 0; i < 200; i++)
    System.out.print( (i%10==9) ? "\\n" : (char)((Math.random() * 94) + 33) );
    }
    }
    자바 문법이 맞는지 모르겠는데 이항 연산자로 줄이면 이렇게 라인을 줄일수 있지요.

  10. BlogIcon ryuda
    2011.08.03 14:57 신고

    감사합니다 !! 잘사용하겠습니다!!
    현재 프로젝트에 적용하려고합니다 문제있으시면 말씀해주세요^^

  11. Gyun
    2011.12.26 17:39 신고

    여기에 추가할만한 아이디어는 음..
    꼭 들어가야 될 애들 즉 대문자 추가 나 특수기호 같은 경우는
    우선순위를 주어 출력시키는 정도가 좋지 않을까합니다.