1.동기
오픈소스를 활용하는 경우에 코드 리뷰가 필요한 경우가 있다
우선 내가 만든 코드도 아니고 거기 코딩 스타일을 따라야 하기 때문에
가끔 코드 리뷰를 물어보고
수정이 필요한 부분 부분 코드 스니핏을 AI(ChatGPT)로 리뷰받고 수정을 해보니 활용할 수 있을 것 같아
어떤식으로 활용하는지 작성해두자
import os
from groq import Groq
import openai
import re
import shutil
from dotenv import load_dotenv
load_dotenv()
# OpenAI API 키와 모델 설정
openai.api_key = os.getenv("OPENAI_API_KEY")
openai_model = os.getenv("OPENAI_API_MODEL")
Groq.api_key = os.getenv("GROQ_API_KEY")
groq_model = os.getenv("GROQ_API_MODEL")
def get_all_files(directory):
files_list = []
for root, dirs, files in os.walk(directory):
for file in files:
files_list.append(os.path.join(root, file))
return files_list
def check_obfuscation(content_chunk, to="groq"):
prompt = f"Is the following code obfuscated? Please answer with 'Yes' or 'No'.\n\n{content_chunk}"
# openai
response_text = ""
if to == "openai":
response = openai.ChatCompletion.create(
model=openai_model,
messages=[{"role": "user", "content": prompt}],
# temperature=0 # 일관된 응답을 위한 설정
)
response_text = response.choices[0].message['content'].strip()
elif to == "groq":
# https://groq.com
response = Groq().chat.completions.create(
model=groq_model,
messages=[{"role": "user", "content": prompt}],
)
response_text = response.choices[0].message.content.strip()
return normalize_response(response_text)
def normalize_response(response):
response_lower = response.lower()
if "yes" in response_lower:
return "Yes"
elif "no" in response_lower:
return "No"
else:
return "Uncertain"
def read_file_and_remove_comments(file_path):
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
content_no_comments = remove_comments(content)
return content_no_comments
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None
def remove_comments(content):
# 모든 주석 제거 (Python, JavaScript, Java, JSP, PHP, Ruby, Go, ASP, HTML, XML 등)
content = re.sub(r'#.*', '', content) # Python, Ruby 라인 주석
content = re.sub(r'//.*', '', content) # C, C++, Java, JavaScript, PHP, Go 라인 주석
content = re.sub(r'/\*.*?\*/', '', content, flags=re.DOTALL) # C, C++, Java, JavaScript, PHP, Go 블록 주석
content = re.sub(r'=begin.*?=end', '', content, flags=re.DOTALL) # Ruby 블록 주석
content = re.sub(r"'[^\n]*", '', content) # ASP 라인 주석
content = re.sub(r'<!--.*?-->', '', content, flags=re.DOTALL) # HTML, XML 주석
return content
def analyze_file_in_chunks(file_content, chunk_size=1000):
chunks = [file_content[i:i + chunk_size] for i in range(0, len(file_content), chunk_size)]
obfuscation_results = [check_obfuscation(chunk) for chunk in chunks]
return obfuscation_results
def main(input_directory, output_directory):
files_list = get_all_files(input_directory)
if not os.path.exists(output_directory):
os.makedirs(output_directory)
obfuscation_results = {}
for file in files_list:
content_no_comments = read_file_and_remove_comments(file)
if content_no_comments:
if len(content_no_comments) < 1000:
print(f"File {file} is smaller than 1000 bytes after removing comments. Skipping.")
# continue
obfuscation_checks = analyze_file_in_chunks(content_no_comments, len(content_no_comments))
else:
obfuscation_checks = analyze_file_in_chunks(content_no_comments, 1000)
# Majority voting or any aggregation logic
if obfuscation_checks.count("Yes") > obfuscation_checks.count("No"):
final_result = "Yes"
else:
final_result = "No"
print(f"chunk : {len(content_no_comments)}") # 추가된 출력문
obfuscation_results[file] = final_result
# 파일 분류 및 복사
if not os.path.exists(output_directory):
os.makedirs(output_directory)
if final_result == "Yes":
result_subdir = os.path.join(output_directory, "obfuscated")
elif final_result == "No":
result_subdir = os.path.join(output_directory, "not_obfuscated")
else:
result_subdir = os.path.join(output_directory, "uncertain")
if not os.path.exists(result_subdir):
os.makedirs(result_subdir)
shutil.copy(file, result_subdir)
return obfuscation_results
# Example usage
input_directory = 'check'
output_directory = 'result'
results = main(input_directory, output_directory)
# Display the results
for file, obfuscation_check in results.items():
print(f"File: {file}")
print(f" Obfuscation Check: {obfuscation_check}")
위 코드는 openapi 와 groq(무료임) api 를 활용해서 파일을 읽어서 난독화(파일을 읽기 어렵게 변환된 텍스트)여부를 구분하는 약 200 줄의 코드이며 코드 리뷰와 수정 사항이 있는지 요청해보자
2.활용
코드 부분과 함께 " 여기 코드 리뷰해줘, 그리고 수정할 부분이 있다면 말해줘" 이렇게 요청 했고
잘 작성된 부분은 언급하면서 리뷰에 대한 내용을 주르륵 작성해준다
수정 제안 사항으로 이야기를 해주고 바로 코드를 작성해주었다
과연 얼마나 잘 작성했을까?
3.결과
결과 비교를 위해 아웃풋을 check_ai.py 로 생성하여 원본과 비교해보았다
수정된 코드와 함께 ChatGPT 답변은 이렇다
그래 알겠다 그럼 제일 중요한 정상적으로 프로그램 실행이 되는지 확인해보았다
당연히 정상적으로 실행되지 않았다
import 문을 왜 수정했는지는 모르겠지만 동작도 되지 않는 코드로 수정해주니 실망했다
그래도 기회는 한번 더 주기 위해
"정상적으로 동작하지 않아" 라고 러프하게 이야기 해보았다
그 다음 수정된 코드를 보았다
import os
import openai
import re
import shutil
from dotenv import load_dotenv
load_dotenv()
# OpenAI API 키와 모델 설정
openai.api_key = os.getenv("OPENAI_API_KEY")
openai_model = os.getenv("OPENAI_API_MODEL")
Groq.api_key = os.getenv("GROQ_API_KEY")
groq_model = os.getenv("GROQ_API_MODEL")
def get_all_files(directory):
files_list = []
for root, dirs, files in os.walk(directory):
for file in files:
files_list.append(os.path.join(root, file))
return files_list
def check_obfuscation(content_chunk, to="groq"):
prompt = f"Is the following code obfuscated? Please answer with 'Yes' or 'No'.\n\n{content_chunk}"
# openai
response_text = ""
if to == "openai":
response = openai.ChatCompletion.create(
model=openai_model,
messages=[{"role": "user", "content": prompt}],
# temperature=0 # 일관된 응답을 위한 설정
)
response_text = response.choices[0].message['content'].strip()
elif to == "groq":
# https://groq.com
response = Groq().chat.completions.create(
model=groq_model,
messages=[{"role": "user", "content": prompt}],
)
response_text = response.choices[0]['message']['content'].strip()
return normalize_response(response_text)
def normalize_response(response):
response_lower = response.lower()
if "yes" in response_lower:
return "Yes"
elif "no" in response_lower:
return "No"
else:
return "Uncertain"
def read_file_and_remove_comments(file_path):
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
content_no_comments = remove_comments(content)
return content_no_comments
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None
def remove_comments(content):
# 모든 주석 제거 (Python, JavaScript, Java, JSP, PHP, Ruby, Go, ASP, HTML, XML 등)
content = re.sub(r'#.*', '', content) # Python, Ruby 라인 주석
content = re.sub(r'//.*', '', content) # C, C++, Java, JavaScript, PHP, Go 라인 주석
content = re.sub(r'/\*.*?\*/', '', content, flags=re.DOTALL) # C, C++, Java, JavaScript, PHP, Go 블록 주석
content = re.sub(r'=begin.*?=end', '', content, flags=re.DOTALL) # Ruby 블록 주석
content = re.sub(r"'[^\n]*", '', content) # ASP 라인 주석
content = re.sub(r'<!--.*?-->', '', content, flags=re.DOTALL) # HTML, XML 주석
return content
def analyze_file_in_chunks(file_content, chunk_size=1000):
chunks = [file_content[i:i + chunk_size] for i in range(0, len(file_content), chunk_size)]
obfuscation_results = [check_obfuscation(chunk) for chunk in chunks]
return obfuscation_results
def create_directory_if_not_exists(directory):
if not os.path.exists(directory):
os.makedirs(directory)
def main(input_directory, output_directory):
files_list = get_all_files(input_directory)
create_directory_if_not_exists(output_directory)
obfuscation_results = {}
for file in files_list:
content_no_comments = read_file_and_remove_comments(file)
if content_no_comments:
if len(content_no_comments) < 1000:
print(f"File {file} is smaller than 1000 bytes after removing comments. Skipping.")
obfuscation_checks = analyze_file_in_chunks(content_no_comments, len(content_no_comments))
else:
obfuscation_checks = analyze_file_in_chunks(content_no_comments, 1000)
if obfuscation_checks.count("Yes") > obfuscation_checks.count("No"):
final_result = "Yes"
else:
final_result = "No"
print(f"chunk : {len(content_no_comments)}") # 추가된 출력문
obfuscation_results[file] = final_result
if final_result == "Yes":
result_subdir = os.path.join(output_directory, "obfuscated")
elif final_result == "No":
result_subdir = os.path.join(output_directory, "not_obfuscated")
else:
result_subdir = os.path.join(output_directory, "uncertain")
create_directory_if_not_exists(result_subdir)
shutil.copy(file, result_subdir)
return obfuscation_results
# Example usage
input_directory = 'check'
output_directory = 'result'
results = main(input_directory, output_directory)
# Display the results
for file, obfuscation_check in results.items():
print(f"File: {file}")
print(f" Obfuscation Check: {obfuscation_check}")
역시 매가 약인가? 기존 코드에서 조금만 수정했다(수정본, 왼쪽)
그래서 코드 결과는? 명령창에서 보이듯 import를 수정해주지는 않았다
홀리 shit!!
그래서 안 고친다,.,,,,,여기서 에러를 피드백하면 고칠 수 있지만 그걸 기대한 것은 아니고
러프한 코드 리뷰 및 수정에 대해 이야기 했을 경우를 기준으로 한 경우이므로 여기까지만 확인하자
3 가지 결론
1. 코드 리뷰는 괜찮은 리뷰성으로 설명해준다
2. 코드 전체를 이해하고 작성하는 것은 아닌 것으로 보여진다(import 문을 삭제하면 안됌)
3. 코드 수정을 할 경우, 모든 부분을 믿는 것이 아닌 왜 수정되었는지를 생각해봐야겠다(AI 만의 스타일이 있는듯...?)
추가 사항
엔트로픽 클로드가 처음 나와서 코드 고쳐달라고 했는데
홀리 shit!!! , chatgpt4o 구독 끊고 cluade 구독해야겟다
'AI' 카테고리의 다른 글
claude 야 대시보드 만들어줘(프로젝트 기능 사용기) (0) | 2024.07.05 |
---|---|
개발자로서 Cluade 3.5 Sonnet 모델 향상 체감하기 (0) | 2024.06.24 |
ChatGPT vs Claude 3 Sonnet (0) | 2024.03.30 |
wit.ai 로 한국어 인식해보기 (1) | 2024.03.28 |
Hugging Face(허깅페이스) API Key 발급하기 (0) | 2024.03.25 |