본문 바로가기

마인크래프트(Minecraft)/Computer Craft

[Computer Craft] 4. 비밀번호 문 예제2

지난 강좌때는 비밀번호 문을 작성했었는데 비밀번호가 소스상에 노출되는 단점을 안고 있었죠? 그래서 이번에는 소스상에 비밀번호를 넣지 않고 다른 파일 공간에 비밀번호를 가져와 사용하는 기법을 소개해요.


1. 파일을 개방하자.  fs.open()


fs api중 하나인 open은.. 파일을 읽기전용이나 쓰기전용으로 읽어 올 수 있어요. 물론 이 결과는 테이블형태로 저장이됩니다. 형태는

fs.open("경로",[r 또는 w 또는 a])

r : 파일을 읽기전용으로 개방한다.

w : 기존에 같은이름으로 된 파일이 있으면 삭제하고 쓰기전용으로 개방한다.

a : 기존에 같은이름으로 된 파일이 있으면 기존의 파일 데이터 끝으로 간후 쓰기전용으로 개방한다.


r은 읽기전용이니, 이미 저장된 값을 가져오는것은 눈치 채셨겠죠.

하지만 w와 a는 이해못하는 분들이 있으니, 한가지 예제를 보여드릴게요.


== a 라는 이름을 가진 파일에 담긴 내용이 show me the money 일때 ==

operation cwal 값을 넣었다고 가정.


fs.open("a","w")

처리1 : a 파일 삭제

처리2 : a파일 생성후 쓰기모드로 변경

처리3 : a파일에 operation cwal 값이 저장

결과 : operation cwal


fs.open("a","a")

처리1 : a 파일 끝으로 이동

처리2 : a 파일 쓰기모드로 변경

처리3 : a파일에 operation cwal 값 추가 저장

결과 : shoe me the moneyoperation cwal


뭐 이런 개념입니다.


저는 이번강좌에서

local file = fs.open("PasswordDB","r")

저는 PasswordDB 라는 파일을 읽기전용으로 불러와서 file 변수로 테이블 핸들러를 대입했어요.



2. 파읽의 데이터 값을 읽어오자 ( file.readLine() , file.readAll() )


파일 읽기 API 는 두가지를 지원하는데요.file.readLine() 와 file.readAll() 에요.

앞의 file 는 fs.open 에서 받아온 변수명이에요.

local hahaha = fs.open("test","r") 이렇게 했다고 가정하면.

hahaha.readLine() 이렇게 쓴다는 거죠...


readLine() 는 파일을 한줄씩 읽어요.

이런 데이터가 있다고 가정한다면,

동해물과 백두산이 마르고 닳도록

하느님이 보우하사 우리나라 만세

무궁화 삼천리 화려강산

대한 사람 대한으로 길이 보전하세.


처음 readLine() 를 실행하면

'동해물과 백두산이 마르고 닳도록' 를 가져오고. 두번째줄 데이터를 읽을 준비를 해요.

또 다시 readLine() 를 실행하면 '하느님이 보우하사 우리나라 만세' 값을 가져오고 세번째줄 라인을 읽어들일 준비를 하게되는거죠.


readAll() 경우에는 모든 라인을 다 읽어오는 것이죠.

되게 단순한 개념인데 강좌로 적으려니 꽤나 어렵네요. 프로그래밍은 역시 직접 하면서 익히는게 제일 좋은거죠 :D



3. read() 함수 암호화 기법

지난 시간엔 read()는 키보드 입력을 받는다고 했었잖아요. 그런데 문제점은 타이핑하게되면 비밀번호가 그대로 찍혀져 나온다는게 문제점이였죠.

read() 에는 문자열 코드를 넣음으로써 비밀번호를 가릴수가 있어요.

사용법은 read("문자") 이렇게 쓰죠. 예문을 보도록할게요.


예문

local input = read("*")

키보드 입력시 : ***** 로 찍혀져나옴.


local input = read("X")

키보드 입력시 : XXXXX 로 찍혀져나옴.


위의 예문에 나오다시피.. 문자열 값을 하나추가하면, 화면상에 비밀번호가 노출될 염려가 없어요. 그러면 비밀번호를 알아내기 쉽지 않게되죠 HAYO!!.

하지만 이것도 완벽한 보안은 아니지만, os.pullEvent 까지 다뤄야만 최강의 보안을 자랑할수있어요. 이건 나중에 설명 할게요.



4. 완성소스 예제 - 주석첨부

local delay = 3
local side = 'right'

while true do
  local file = fs.open("PasswordDB","r") -- PasswordDB 라는 이름을 가진 파일을 읽기전용으로 개방. 반환된 테이블 값을 file 변수에 저장
  password = file.readLine() -- 파일 한줄을 읽어와 password 변수에 저장. file 핸들러의 포인터는 두번째줄을 가리킨다.
  term.clear()
  term.setCursorPos(1,1)
  write("Password : ")
  local input = read("*") -- 키입력을 받는다. 이때 키보드 입력하는것은 * 로 출력한다.
  term.clear()
  term.setCursorPos(1,1)
  if password == input then
    print("Open the door")
    redstone.setOutput(side,true)
    os.sleep(delay)
    redstone.setOutput(side,false)
  else
    print("Sorry, try again")
    os.sleep(delay)
  end
end



5. 시연영상




6. 문제점.

os.pullEvent 발생시 비밀번호를 외부인이 확인이 가능하다.


7. 부록 (복붙용 소스)

local delay = 3
local side = 'right'

while true do
  local file = fs.open("PasswordDB","r")
  password = file.readLine()
  term.clear()
  term.setCursorPos(1,1)
  write("Password : ")
  local input = read("*")
  term.clear()
  term.setCursorPos(1,1)
  if password == input then
    print("Open the door")
    redstone.setOutput(side,true)
    os.sleep(delay)
    redstone.setOutput(side,false)
  else
    print("Sorry, try again")
    os.sleep(delay)
  end
end