Tempo Di Valse

[Node.js] 파일 비교하여 같은 파일인 지 확인하기 본문

개발/Web

[Node.js] 파일 비교하여 같은 파일인 지 확인하기

TempoDiValse 2022. 4. 6. 11:01

A 파일과 B 파일이 같은 파일인 지 다른 파일인 지 비교하고 싶었다.

 

맨 처음 접근하고자 했을 때에는 (파일명, 파일 사이즈) 를 통해 접근하면 괜찮지 않을까 싶었지만, 파일을 다른 이름으로 변경을 하거나 내용이 다른데 같은 사이즈의 데이터가 된다면 무용지물이기 때문에 어떻게 처리할 수 있는 방법이 없을까 찾아보다가 "파일 해쉬" 에 대한 내용을 구글링하다가 발견하게 되었다. 이 방식은 파일 자체를 해쉬 값으로 변경하여 비교를 하게되면, 파일 내용 자체를 변환하여 비교한 것이기 떄문에 파일이 다른 이름으로 변경이 되거나 해도 같은 지 다른 지 확인할 수 있다는 것이다. 꽤나 괜찮은 방법이라 생각하여 Node.js 환경에서는 어떻게 하면 가능한 지 찾아보니 'crypto' 모듈을 활용하면 쉽게 구현할 수 있다는 것을 확인했다.

 

1. 구현

 먼저 crypto 라이브러리는 Node.js 에서 기본으로 제공해주는 모듈이기 때문에 NPM 을 통해서 설치하지 않아도 사용을 할 수 있다.

const crypto = require('crypto')

 그리고 비교하고자 하는 A 와 B 파일을 해쉬값으로 만들도록 한다. '해쉬 값을 만든다' 라고 얘기하고 실제 구현하는 것은 단방향 암호화를 하게 되는데, 알고리즘에는 MD5 를 사용하는 사람도 있고 SHA256 을 사용하는 사람이 있고 하다. 요즘에는 MD5를 사용하는 것을 권장하지 않기 때문에 SHA256 을 사용하여 해쉬 값을 발급하도록 하겠다.

const fs = require('fs').promise
const crypto = require('crypto')


/* ...Codes */

async function hash(src){
    const buffer = await fs.readFile(src)

    const sha256 = crypto.createHash('sha256')
    sha256.update(buffer)

    return sha256.digest('hex')
}

/* ...Codes */

해쉬값은 파일 내용을 통해서 만들어지기 때문에 파일을 읽을 수 있는 fs 모듈을 불러올 필요가 있다. async/await 로 편하게 하기 위해서 fs 모듈을 promise 형으로 불러왔다. crypto 의 createHash 메소드를 통해서 초기화를 하게 되는데, 재사용이 되는 객체는 아니기 때문에 따로 Global 로 빼서 update -> digest 하여 사용할 수 없다. 그래서 해쉬값을 구할 때 마다 createHash 를 부르도록 한다.

 

파일을 읽은 버퍼를 SHA256 을 통해 변환하게 되면,

이런 값을 생성하게 된다. 이 값은 파일명을 변경해도 그 값이지만 파일을 변경하면 값은 바뀌게된다. 그래서 파일이 폴더 내에 하나만 유지하려 하거나 같은 내용의 파일을 찾고자 할 때에는 유용한 방법이지 않을까 싶다.


파일 해시 값을 통한 비교는 Node.js 이외에도 다른 언어에서도 사용할 수 있는 방법이라서 각 언어별로 I/O 를 만지는 부분에서는 유용하게 사용할 수 있을 것 같다.

반응형
Comments