204 lines
6.2 KiB
Python
204 lines
6.2 KiB
Python
"""
|
|
In-Sight 2001C-353 트리거 후 전체 셀 스캔 스크립트
|
|
SE8 트리거 실행 → 결과 갱신 완료 후 A0~Z50 범위 GV 스캔.
|
|
결과는 콘솔 출력과 find_cells_trigger_result.txt 에 동시 저장.
|
|
"""
|
|
|
|
import socket
|
|
import string
|
|
import time
|
|
|
|
IP = "169.254.0.1"
|
|
PORT = 23
|
|
COLS = list(string.ascii_uppercase) # A ~ Z (26개)
|
|
ROWS = range(0, 251) # 0 ~ 250 (251개) → 총 6526셀
|
|
RESULT_FILE = "find_cells_trigger_result.txt"
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# 저수준 소켓 헬퍼 (insight.py 방식 동일)
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def _read_line(sock: socket.socket, buf: bytearray) -> str:
|
|
"""버퍼에서 \\r\\n까지 읽어 문자열로 반환. 남은 데이터는 buf에 보존."""
|
|
while b"\r\n" not in buf:
|
|
try:
|
|
chunk = sock.recv(4096)
|
|
except socket.timeout:
|
|
break
|
|
if not chunk:
|
|
break
|
|
buf += chunk
|
|
|
|
if b"\r\n" in buf:
|
|
idx = buf.index(b"\r\n")
|
|
line = bytes(buf[:idx])
|
|
del buf[:idx + 2]
|
|
else:
|
|
line = bytes(buf)
|
|
buf.clear()
|
|
|
|
for encoding in ["euc-kr", "cp949", "utf-8"]:
|
|
try:
|
|
return line.decode(encoding).strip()
|
|
except Exception:
|
|
continue
|
|
return line.decode(errors="ignore").strip()
|
|
|
|
|
|
def _send(sock: socket.socket, cmd: str):
|
|
sock.sendall((cmd + "\r\n").encode())
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# 로그인 (insight.py connect() 시퀀스와 동일)
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def _login(sock: socket.socket, buf: bytearray):
|
|
banner = _read_line(sock, buf)
|
|
print(f"[연결] 배너: {banner!r}")
|
|
|
|
_send(sock, "admin")
|
|
while b"Password:" not in buf:
|
|
try:
|
|
chunk = sock.recv(4096)
|
|
except socket.timeout:
|
|
break
|
|
if not chunk:
|
|
break
|
|
buf += chunk
|
|
prompt = buf.decode(errors="ignore").strip()
|
|
buf.clear()
|
|
print(f"[연결] 프롬프트: {prompt!r}")
|
|
|
|
sock.sendall(b"\r\n") # 빈 비밀번호
|
|
result = _read_line(sock, buf)
|
|
print(f"[연결] 로그인: {result!r}")
|
|
|
|
if "Logged In" not in result:
|
|
raise RuntimeError(f"로그인 실패: {result!r}")
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# SE8 트리거
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def _trigger(sock: socket.socket, buf: bytearray):
|
|
"""SE8 소프트웨어 트리거 전송 후 응답 수신."""
|
|
_send(sock, "SE8")
|
|
response = _read_line(sock, buf)
|
|
print(f"[트리거] SE8 응답: {response!r}")
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# 셀 스캔
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def _scan(sock: socket.socket, buf: bytearray) -> dict:
|
|
"""GV[열][행] 전체 스캔 → {셀주소: 값문자열}"""
|
|
total = len(COLS) * len(ROWS)
|
|
found = {}
|
|
|
|
for col in COLS:
|
|
for row in ROWS:
|
|
cell = f"{col}{row}"
|
|
_send(sock, f"GV{cell}")
|
|
|
|
status = _read_line(sock, buf) # "1" 또는 "0"
|
|
|
|
if status == "1":
|
|
value = _read_line(sock, buf)
|
|
if not value.strip():
|
|
pass
|
|
else:
|
|
found[cell] = value
|
|
try:
|
|
print(f"\r[{cell:<4}] = {value:<40}")
|
|
except UnicodeEncodeError:
|
|
print(f"\r[{cell:<4}] = {value.encode('utf-8', errors='replace')!r}")
|
|
|
|
done = (COLS.index(col)) * len(ROWS) + row + 1
|
|
print(
|
|
f"스캔 중... [{cell} / Z{ROWS[-1]}] ({done}/{total})",
|
|
end="\r", flush=True,
|
|
)
|
|
|
|
print() # 진행바 줄 정리
|
|
return found
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# 결과 저장
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def _save(found: dict, path: str = RESULT_FILE):
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
f.write(f"스캔 범위: A0 ~ Z{ROWS[-1]} / 유효 셀: {len(found)}개\n")
|
|
f.write("=" * 40 + "\n")
|
|
for cell, val in found.items():
|
|
f.write(f"[{cell:<4}] = {val}\n")
|
|
print(f"결과 저장 완료 → {path}")
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# 값 검색
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def _search(found: dict, query: str):
|
|
matches = {c: v for c, v in found.items() if query.lower() in v.lower()}
|
|
if matches:
|
|
print(f"\n[검색] '{query}' 포함 셀 {len(matches)}개:")
|
|
for cell, val in matches.items():
|
|
print(f" [{cell:<4}] = {val}")
|
|
else:
|
|
print(f"[검색] '{query}'를 포함한 셀이 없습니다.")
|
|
|
|
|
|
# ------------------------------------------------------------------ #
|
|
# 메인
|
|
# ------------------------------------------------------------------ #
|
|
|
|
def main():
|
|
print(f"[연결] {IP}:{PORT} 접속 중...")
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
sock.settimeout(3.0)
|
|
sock.connect((IP, PORT))
|
|
buf = bytearray()
|
|
|
|
try:
|
|
_login(sock, buf)
|
|
|
|
input("\n준비됐으면 엔터를 누르세요 (리플렉터를 카메라 앞에 올려두세요): ")
|
|
|
|
print("[트리거] SE8 전송 중...")
|
|
_trigger(sock, buf)
|
|
|
|
print("[대기] 카메라 처리 완료 대기 (1초)...")
|
|
time.sleep(1)
|
|
|
|
print(f"\n스캔 시작: A0 ~ Z{ROWS[-1]} (총 {len(COLS) * len(ROWS)}셀)\n")
|
|
found = _scan(sock, buf)
|
|
finally:
|
|
sock.close()
|
|
|
|
print(f"\n스캔 완료. 총 {len(found)}개 셀 발견")
|
|
print("=" * 40)
|
|
for cell, val in found.items():
|
|
try:
|
|
print(f" [{cell:<4}] = {val}")
|
|
except UnicodeEncodeError:
|
|
print(f" [{cell:<4}] = {val.encode('utf-8', errors='replace')!r}")
|
|
|
|
_save(found)
|
|
|
|
print()
|
|
while True:
|
|
query = input("찾는 값 입력 (엔터 시 종료): ").strip()
|
|
if not query:
|
|
break
|
|
_search(found, query)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|