2024 여름 SWLUG/개인정보보호 프로젝트

[파이썬]데이터 비식별화 코드 최종 + 웹 개발 기초 및 기획

un_plugged 2024. 8. 18. 15:52
import pandas as pd
import hashlib

# CSV 파일 경로 설정
input_file_path = 'C:/Users/82106/Desktop/test2.csv'
output_file_path = 'C:/Users/82106/Desktop/test2_processed.csv'

# CSV 파일 읽기 (한글 처리 위해 cp949 인코딩 사용)
data = pd.read_csv(input_file_path, encoding='cp949')

# 환자ID 마스킹 처리 함수
def mask_id(index):
    return 'ID' + str(index).zfill(4)

# 이름 마스킹 처리 함수 (성을 제외하고 마스킹)
def mask_name(name):
    return name[0] + "*" * (len(name) - 1)

# 나이 범주화 함수
def categorize_age(age):
    if age < 10:
        return '10세 미만'
    elif 10 <= age < 20:
        return '10대'
    elif 20 <= age < 30:
        return '20대'
    elif 30 <= age < 40:
        return '30대'
    elif 40 <= age < 50:
        return '40대'
    elif 50 <= age < 60:
        return '50대'
    elif 60 <= age < 70:
        return '60대'
    elif 70 <= age < 80:
        return '70대'
    elif 80 <= age < 90:
        return '80대'
    else:
        return '90대 이상'

# 주민등록번호 마스킹 처리 함수 (뒷자리 마스킹)
def mask_ssn(ssn):
    return ssn[:7] + '-' + '*******'

# 주소 마스킹 처리 함수 (시, 도까지만 표시)
def mask_address(address):
    parts = address.split(' ')
    return parts[0] + ' ' + parts[1] + ' ***'

# 질병코드 SHA-256 암호화 처리 함수
def sha256_encode(code):
    return hashlib.sha256(code.encode()).hexdigest()

# 환자ID 마스킹 처리
data['환자ID'] = data.index.map(mask_id)

# 이름 마스킹 처리
if '이름' in data.columns:
    data['이름'] = data['이름'].apply(mask_name)
else:
    print("CSV 파일에 '이름' 열이 없습니다.")

# 나이 범주화 처리
if '나이' in data.columns:
    data['나이'] = data['나이'].apply(categorize_age)
else:
    print("CSV 파일에 '나이' 열이 없습니다.")

# 주민등록번호 마스킹 처리
if '주민등록번호' in data.columns:
    data['주민등록번호'] = data['주민등록번호'].apply(mask_ssn)
else:
    print("CSV 파일에 '주민등록번호' 열이 없습니다.")

# 주소 마스킹 처리
if '주소' in data.columns:
    data['주소'] = data['주소'].apply(mask_address)
else:
    print("CSV 파일에 '주소' 열이 없습니다.")

# 질병코드 SHA-256 암호화 처리
if '질병코드' in data.columns:
    data['질병코드'] = data['질병코드'].apply(sha256_encode)
else:
    print("CSV 파일에 '질병코드' 열이 없습니다.")

# 비식별화 처리된 데이터를 새로운 CSV 파일로 저장 (utf-8-sig 인코딩 사용)
data.to_csv(output_file_path, index=False, encoding='utf-8-sig')

print("비식별화 처리된 데이터가 저장되었습니다.")

위의 코드는 우리 팀 최종 데이터 비식별화 코드이다. 주석에 블록 별 기능에 대한 설명을 달아놓았지만 좀 더 구체적으로 분석해보겠다.

 

1. CSV 파일 경로 설정 및 데이터 읽기

import pandas as pd
import hashlib

# CSV 파일 경로 설정
input_file_path = 'C:/Users/82106/Desktop/test2.csv'
output_file_path = 'C:/Users/82106/Desktop/test2_processed.csv'

# CSV 파일 읽기 (한글 처리 위해 cp949 인코딩 사용)
data = pd.read_csv(input_file_path, encoding='cp949')

 

  • pandas 라이브러리는 데이터 처리에, hashlib는 암호화에 사용됨
  • input_file_path와 output_file_path 변수에 각각 입력 파일과 출력 파일의 경로를 저장
  • pd.read_csv 함수를 사용해 CSV 파일을 읽어온다. 추가로 한글 처리 문제를 해결하기 위해 cp949 인코딩을 사용하여 파일을 읽는다.

2. 마스킹 및 변환 함수 정의

# 환자ID 마스킹 처리 함수
def mask_id(index):
    return 'ID' + str(index).zfill(4)

# 이름 마스킹 처리 함수 (성을 제외하고 마스킹)
def mask_name(name):
    return name[0] + "*" * (len(name) - 1)

# 나이 범주화 함수
def categorize_age(age):
    if age < 10:
        return '10세 미만'
    elif 10 <= age < 20:
        return '10대'
    elif 20 <= age < 30:
        return '20대'
    elif 30 <= age < 40:
        return '30대'
    elif 40 <= age < 50:
        return '40대'
    elif 50 <= age < 60:
        return '50대'
    elif 60 <= age < 70:
        return '60대'
    elif 70 <= age < 80:
        return '70대'
    elif 80 <= age < 90:
        return '80대'
    else:
        return '90대 이상'

 

 

  • mask_id 함수: 각 환자 ID를 마스킹한다. 인덱스를 받아 네 자리로 맞춘 후 앞에 ID를 붙여 새로운 환자 ID를 생성하는 방식이다. 
  • mask_name 함수: 성을 제외한 나머지 글자를 *로 대체하는 이름 마스킹 함수이다. 
  • categorize_age 함수: 나이대에 맞춰 나이를 나눈다.

3. 주민등록번호, 주소 마스킹 및 질병코드 암호화 함수 정의

# 주민등록번호 마스킹 처리 함수 (뒷자리 마스킹)
def mask_ssn(ssn):
    return ssn[:7] + '-' + '*******'

# 주소 마스킹 처리 함수 (시, 도까지만 표시)
def mask_address(address):
    parts = address.split(' ')
    return parts[0] + ' ' + parts[1] + ' ***'

# 질병코드 SHA-256 암호화 처리 함수
def sha256_encode(code):
    return hashlib.sha256(code.encode()).hexdigest()

 

 

  • mask_ssn 함수: 주민등록번호의 앞 7자리는 그대로 두고, 뒷자리는 *******로 마스킹한다.
  • mask_address 함수: 주소를 시와 도까지만 표시하고, 나머지는 ***로 마스킹한다.
  • sha256_encode 함수: 질병코드를 SHA-256 알고리즘을 사용해 암호화한다. hashlib.sha256을 사용해 문자열을 해시값으로 변환한다.

4. 데이터 프레임에 마스킹 및 변환 적용

# 환자ID 마스킹 처리
data['환자ID'] = data.index.map(mask_id)

# 이름 마스킹 처리
if '이름' in data.columns:
    data['이름'] = data['이름'].apply(mask_name)
else:
    print("CSV 파일에 '이름' 열이 없습니다.")

# 나이 범주화 처리
if '나이' in data.columns:
    data['나이'] = data['나이'].apply(categorize_age)
else:
    print("CSV 파일에 '나이' 열이 없습니다.")

# 주민등록번호 마스킹 처리
if '주민등록번호' in data.columns:
    data['주민등록번호'] = data['주민등록번호'].apply(mask_ssn)
else:
    print("CSV 파일에 '주민등록번호' 열이 없습니다.")

# 주소 마스킹 처리
if '주소' in data.columns:
    data['주소'] = data['주소'].apply(mask_address)
else:
    print("CSV 파일에 '주소' 열이 없습니다.")

# 질병코드 SHA-256 암호화 처리
if '질병코드' in data.columns:
    data['질병코드'] = data['질병코드'].apply(sha256_encode)
else:
    print("CSV 파일에 '질병코드' 열이 없습니다.")

각 열에 대해 앞에서 정의한 함수들을 적용한다. 

  • 환자ID: 인덱스를 이용해 mask_id 함수 적용
  • 이름, 나이, 주민등록번호, 주소, 질병코드: 해당 열이 있는지 확인한 후, 존재하면 각각의 함수 (mask_name, categorize_age, mask_ssn, mask_address, sha256_encode)를 적용
  • 열이 존재하지 않을 경우, 콘솔에 열이 없음을 알리는 메시지를 출력

5. 결과 저장

# 비식별화 처리된 데이터를 새로운 CSV 파일로 저장 (utf-8-sig 인코딩 사용)
data.to_csv(output_file_path, index=False, encoding='utf-8-sig')

print("비식별화 처리된 데이터가 저장되었습니다.")

 

  • 모든 처리가 완료된 후, 비식별화된 데이터를 새로운 CSV 파일로 저장한다. 저장 시 utf-8-sig 인코딩을 사용해 한글이 깨지지 않도록 한다. 
  • 마지막으로 작업이 완료되었음을 알리는 메시지를 출력한다. 

실행 결과

위의 코드로 실행을 했더니 원본 파일에서의 환자 ID 열이 아닌 아래와 같이 마스킹 처리 된 열이 새롭게 추가된다. 이 부분은 다음 회의 때 팀원들과 논의 후 수정하도록 하겠다...

 

 

 

 

웹 개발 기초

웹 개발은 크게 프론트엔드(클라이언트 측)와 백엔드(서버 측) 두가지로 나뉘어져 있다. 프론트엔드는 사용자 인터페이스와 사용자 경험을 개발하고, 백엔드는 네트워크 관리와 데이터 처리를 담당한다.

 

아마 나는 프론트엔드를 맡을 가능성이 높아 이 글에서는 프론트엔드를 중점으로 학습해보겠다. html과 css는 이미 구루에서 배웠기 때문에 자바 스크립트 위주로 공부할 것이다.

 

웹 개발 과정

웹 개발은 크게 "기획(모델링) -> 개발(프론트, 백) -> 테스트(QA)" 과정으로 이루어져있다. 우리 팀 역시 이와 같은 순서를 거쳐 개발을 진행할 것이다. 

 

1. 프론트엔드

완성된 디자인 이미지를 토대로 인터넷 문서인 HTML을 작성하고 CSS를 이용해 화면의 모양을 잡아 정적인 웹 문서를 완성한다.

이렇게 완성된 웹 문서는 단순히 웹 브라우저에서 보이기만 할 뿐 동작은 하지 않는다. 따라서 자바 스크립트를 통해 웹브라우저 자체의 내장 컴파일 기능을 이용하여 페이지를 동적으로 변형하고 이벤트를 발생시킨다. 

 

프론트엔드 개발은 다음 3가지 언어로 구성된다. 

 

  • HTML: 요소들을 배치하고 구조를 형성하기 위한 언어
  • CSS: 배치된 요소들을 디자인하고 색을 입히고 꾸미기 위한 언어
  • 자바 스크립트: HTML과 CSS로 구성된 웹 페이지를 동적으로 만들어주는 언어

즉, HTML 코드로 페이지의 틀을 만들고 CSS 코드로 그 페이지의 틀을 꾸미고 재배치한 후 자바스크립트 코드로 페이지를 동적으로 만드는 것이 프론트엔드가 하는 일이다. 

 

자바 스크립트 시작하기

자바 스크립트를 위해 프로그램을 따로 설치해야하는 줄 알았지만...이미 내가 사용하고 있는 VS CODE를 활용한다길래 설치 과정은 건너뛰도록 하겠다.

보통은 자바스크립트 코드를 .js 파일에 따로 분리해서 작성하는 편이다.

 

https://doongdoongeee.tistory.com/146

 

JavaScript 시작하기(다운로드 및 기본 설정)

자바 스크립트는 웹에서 발생하는 이벤트를 처리하고 GUI의 구성을 프로그래밍하기 위한 언어이므로 웹 브라우저가 필요하다. 윈도우의 경우 기본 웹브라우저가 Microsoft Edge로 설정되어있겠지만

doongdoongeee.tistory.com

위의 글을 참고하여 실습해보았다.

Live server 설치 후 change-1.html 문서의 아무 열이나 우클릭 하여 Live server를 열었더니 아래와 같이 브라우저가 나타난다.

이는 html 문서의 실행결과이고 자바 스크립트 언어를 적용하여 실행 결과를 확인해보겠다.

 

이 태그는 js 폴더 안에 있는 change.js라는 JavaScript 파일을 HTML 문서에 포함시켜, 그 안에 있는 JavaScript 코드가 실행되도록 한다. 

 

텍스트 클릭 시 색깔이 바뀌는 동적 페이지로 만들어졌다. 

 

※자바스크립트 소스코드를 실행시키는 방법

  1. HTML 파일에 <script> 태그를 만들고 그 안에 코드를 넣는 방법
  2. HTML 파일에서 script 파일의 경로를 입력하고 import 하는 방법( 외부 JavaScript 파일을 포함시켜 그 파일에 작성된 JavaScript 코드를 HTML 문서에서 사용할 수 있게 한다는 의미)

매우 짧은 코드가 아닌 이상 2번째 방식이 훨씬 더 많이 쓰인다.

 

※js 파일에 들어가는 내용

JavaScript 파일(.js)에는 웹페이지의 동작을 제어하는 코드가 들어간다. 예를 들어, HTML 요소에 이벤트를 추가하거나, 데이터를 처리하거나, DOM(Document Object Model)을 조작하는 코드 등이 포함된다. 

우리 팀의 웹페이지에는 파일 업로드 기능이 들어갈 예정인데 이 기능을 자바 스크립트 파일에 작성하면 된다! 


html 태그

이미 구루에서 배웠지만 간단하게 다시 복습해보겠다.

  • <태그이름> 내용 </태그이름> : 태그의 시작과 끝, 그 안에 다른 태그를 넣거나 내용을 넣을 수 있다. 대부분의 태그들은 여는 태그와 닫는 태그로 되어 있다.
    • 열거나 닫지 않는 '단일 태그' 도 있다. (예: <img /> 또는 <input />
  • <html> : html 전체를 감싸는 태그
  • <head> : 시각적으로 보이지 않으면서, html 에 대한 여러 가지 초기 설정 등을 구성할 수 있는 태그
  • <body> : 시각적으로 보이는 태그들을 작성하는 영역. 각종 요소(제목, 본문, 이미지, 버튼, 링크 등)들이 표현되는 태그
  • <h1> : 문서의 제목(heading 1)을 표현하는 태그
  • <script> : 자바스크립트 태그. 자바스크립트가 실행되는 영역, 보편적으로 <script> 태그는 body 태그의 끝인 </body> 직전에 위치하는 편이다.
    • <script> 태그 내에 작성된 console.log() 는 우리가 파이썬에서 print() 함수를 써서 콘솔 창에 결과를 출력한 것과 똑같은 역할을 한다.

 

 

 

2. 백엔드

장고의 특징과 프로그램 설치

장고는 현재 가장 많이 사용되는 파이썬 웹 프레임워크이다. 이러한 장고 웹 프레임워크의 주요 기능은 아래와 같다.

 

1. MVC 패턴 기반 MVT:  MVT 프레임워크라고도 하는 “모델, 뷰, 템플릿” 프레임워크로 구성되어 있다. 

※ 장고에서의 MVT

Model: 데이터베이스에 엑세스

View: 데이터를 가져오고 변형

Template: 데이터를 사용자에게 보여줌

 

2. 객체 관계 매핑: 데이터베이스 시스템과 모델이라는 파이썬 클래스를 연결하는 다리와 같은 역할을 하여 다양한 데이터베이스 시스템을 지원하며 SQL 문장을 사용하지 않고도 테이블을 조작할 수 있다. 또한, 설정을 조금만 변경하면 이미 구축한 데이터베이스 시스템을 다른 데이터베이스로 쉽고 편리하게 변경할 수 있다.

 

3. 자동으로 구성되는 관리자 화면: 데이터베이스 관리 기능을 위한 관리자 화면을 프로젝트를 시작하는 시점에 기본 기능으로 제공한다. 이러한 관리자 화면을 통해서 애플리케이션에서 사용하는 테이블과 데이터를 쉽게 생성하거나 변경할 수 있어 개발자가 별도로 관리 기능을 개발할 필요가 없다.

 

4. 우아한 URL 설계: 우아한 URL 방식을 채택하여 URL을 직관적이고 쉽게 표현할 수 있으며 이해하기 쉬운 코드 작성과 편리한 개발이 가능하다.

 

5. 자체 탬플릿 시스템: 화면 디자인과 로직에 관한 코딩을 분리하여 독립적으로 프로그래밍이 가능하다. 특히 HTML과 같은 텍스트형 언어를 쉽게 다룰 수 있도록 개발되었다.

 

6. 캐시 시스템:주 이용되는 내용을 저장한 캐시 페이지를  메모리, 데이터베이스 내부, 파일 시스템  중 아무 곳에나 저장하였다가 재사용하여 성능을 높인다. 

 

장고 라이브러리는 다운을 이미 받았고 장고를 사용하기 위해서는 장고 프로젝트를 시작해야 한다.

대부분의 경우 하나의 웹 서비스는 하나의 장고 프로젝트로 이루어져 있고, 그 내부에 여러개의 기능(App)으로 구성되어 있다.

 

백엔드를 맡게 된다면 그때 장고에 대해 좀 더 공부해보겠다. 

 

 

 

웹 페이지 기획

이 정도로 구조를 짜보았다. 

  • 시간이 많이 걸리지 않았다면 마이페이지까지 제작하면 좋겠지만...시간 관계 상 그냥 파일 업로드만 있는 페이지로 제작하게 될듯
  • 처리 완료 시 자동으로 사용자의 컴퓨터에 저장되도록 함