"""
규제 문서에서 정보를 추출하는 유틸리티 함수들
- extract_regulation_id: 규제 ID 추출
- extract_requirements: 요구사항 리스트 추출
- extract_keywords: 기술 키워드 추출
- recommend_aws_services: AWS 서비스 추천
- assess_difficulty: 난이도 평가
- estimate_implementation_days: 구현 일수 추정
"""
import re
from typing import List
def extract_regulation_id(text: str) -> str:
"""
규제 ID를 추출합니다.
지원하는 패턴:
- ISMS-P 2.8.1, ISMS-P 2-8-1
- NIST AC-2, NIST SC-13
- CIS 1.1, CIS 2.1.1
Args:
text: 분석할 규제 텍스트
Returns:
str: 추출된 규제 ID 또는 "Unknown"
"""
patterns = [
r'ISMS-?P\s*(\d+[.\-]\d+[.\-]\d+)',
r'NIST\s+([A-Z]{2}-\d+)',
r'CIS\s+(\d+\.\d+(?:\.\d+)?)'
]
for pattern in patterns:
match = re.search(pattern, text, re.IGNORECASE)
if match:
return match.group(0)
return "Unknown"
def extract_requirements(text: str) -> List[str]:
"""
규제 텍스트에서 요구사항을 추출합니다.
지원하는 패턴:
- "-" 또는 "• "로 시작하는 줄
- "1.", "2." 등 숫자로 시작하는 줄
- "가.", "나." 등 한글로 시작하는 줄
- "①", "②" 등 원문자로 시작하는 줄
Args:
text: 분석할 규제 텍스트
Returns:
List[str]: 추출된 요구사항 리스트
"""
requirements = []
lines = text.split('\n')
for line in lines:
stripped = line.strip()
# 빈 줄 건너뛰기
if not stripped:
continue
# 패턴 매칭: -, •, 숫자., 한글., 원문자
if re.match(r'^[-•]\s+', stripped):
# - 또는 • 로 시작하는 경우
clean = re.sub(r'^[-•]\s+', '', stripped)
if clean:
requirements.append(clean)
elif re.match(r'^\d+\.\s+', stripped):
# 1. 2. 등 숫자로 시작하는 경우
clean = re.sub(r'^\d+\.\s+', '', stripped)
if clean:
requirements.append(clean)
elif re.match(r'^[가-힣]\.\s*', stripped):
# 가. 나. 등 한글로 시작하는 경우
clean = re.sub(r'^[가-힣]\.\s*', '', stripped)
if clean:
requirements.append(clean)
elif re.match(r'^[①②③④⑤⑥⑦⑧⑨⑩]\s*', stripped):
# 원문자로 시작하는 경우
clean = re.sub(r'^[①②③④⑤⑥⑦⑧⑨⑩]\s*', '', stripped)
if clean:
requirements.append(clean)
return requirements
def extract_keywords(text: str) -> List[str]:
"""
텍스트에서 기술 키워드를 추출합니다.
사전 정의된 키워드 맵핑을 사용하여
관련 기술 용어를 추출합니다.
Args:
text: 분석할 규제 텍스트
Returns:
List[str]: 추출된 기술 키워드 리스트
"""
keyword_map = {
"접근": ["IAM", "접근제어", "인증"],
"권한": ["IAM", "권한관리", "최소권한"],
"암호화": ["KMS", "암호화", "encryption"],
"암호": ["KMS", "암호화", "encryption"],
"로그": ["CloudTrail", "로깅", "감사"],
"감사": ["CloudTrail", "로깅", "감사추적"],
"네트워크": ["VPC", "보안그룹", "네트워크"],
"방화벽": ["VPC", "보안그룹", "WAF"],
"백업": ["Backup", "스냅샷", "복구"],
"복구": ["Backup", "DR", "복구"],
"모니터링": ["CloudWatch", "알림", "모니터링"],
"알림": ["CloudWatch", "SNS", "알림"],
"인증": ["IAM", "MFA", "인증"],
"저장": ["S3", "스토리지", "저장"],
"데이터": ["데이터보호", "DLP"],
"취약점": ["Inspector", "취약점분석"],
"패치": ["Systems Manager", "패치관리"],
"설정": ["Config", "설정관리"],
}
found = set()
text_lower = text.lower()
for key, values in keyword_map.items():
if key in text_lower:
found.update(values)
return list(found) if found else ["일반"]
def recommend_aws_services(keywords: List[str]) -> List[str]:
"""
키워드 기반으로 AWS 서비스를 추천합니다.
Args:
keywords: 기술 키워드 리스트
Returns:
List[str]: 추천 AWS 서비스 리스트
"""
service_map = {
"IAM": ["AWS IAM", "AWS IAM Identity Center"],
"접근제어": ["AWS IAM", "AWS Resource Access Manager"],
"인증": ["AWS IAM", "Amazon Cognito"],
"MFA": ["AWS IAM MFA"],
"KMS": ["AWS KMS"],
"암호화": ["AWS KMS", "AWS Certificate Manager"],
"encryption": ["AWS KMS", "AWS CloudHSM"],
"CloudTrail": ["AWS CloudTrail"],
"로깅": ["AWS CloudTrail", "Amazon CloudWatch Logs"],
"감사": ["AWS CloudTrail", "AWS Audit Manager"],
"VPC": ["Amazon VPC"],
"보안그룹": ["Amazon VPC Security Groups"],
"네트워크": ["Amazon VPC", "AWS Network Firewall"],
"WAF": ["AWS WAF"],
"Backup": ["AWS Backup"],
"스냅샷": ["Amazon EBS Snapshots", "AWS Backup"],
"복구": ["AWS Backup", "AWS Elastic Disaster Recovery"],
"CloudWatch": ["Amazon CloudWatch"],
"모니터링": ["Amazon CloudWatch", "AWS X-Ray"],
"알림": ["Amazon SNS", "Amazon CloudWatch Alarms"],
"S3": ["Amazon S3"],
"스토리지": ["Amazon S3", "Amazon EBS"],
"Inspector": ["Amazon Inspector"],
"취약점분석": ["Amazon Inspector", "AWS Security Hub"],
"Systems Manager": ["AWS Systems Manager"],
"패치관리": ["AWS Systems Manager Patch Manager"],
"Config": ["AWS Config"],
"설정관리": ["AWS Config", "AWS Systems Manager"],
}
services = set()
for keyword in keywords:
if keyword in service_map:
services.update(service_map[keyword])
return list(services) if services else ["AWS Config", "AWS Security Hub"]
def assess_difficulty(text: str) -> str:
"""
규제 텍스트의 구현 난이도를 평가합니다.
Args:
text: 분석할 규제 텍스트
Returns:
str: "쉬움", "보통", "어려움" 중 하나
"""
text_lower = text.lower()
hard_keywords = ["복잡", "다중", "통합", "연계", "고급", "실시간", "자동화", "전체"]
easy_keywords = ["간단", "기본", "단순", "설정", "확인", "점검"]
hard_count = sum(1 for kw in hard_keywords if kw in text_lower)
easy_count = sum(1 for kw in easy_keywords if kw in text_lower)
if hard_count >= 2 or (hard_count > easy_count and hard_count >= 1):
return "어려움"
elif easy_count >= 2 or (easy_count > hard_count and easy_count >= 1):
return "쉬움"
else:
return "보통"
def estimate_implementation_days(difficulty: str) -> int:
"""
난이도 기반으로 구현 예상 일수를 추정합니다.
Args:
difficulty: 난이도 ("쉬움", "보통", "어려움")
Returns:
int: 예상 구현 일수
"""
days_map = {
"쉬움": 2,
"보통": 5,
"어려움": 10
}
return days_map.get(difficulty, 5)