From 8505f4b7be6013ade5f78cd8f19ef259513a1ee8 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 13 Sep 2026 14:43:24 +0900 Subject: [PATCH] =?UTF-8?q?knowledge(=EA=B2=BD=EC=9F=81=EC=82=AC):=20?= =?UTF-8?q?=EC=95=94=ED=98=B8=ED=99=94=20=EC=9E=90=EB=A3=8C=EC=9D=98=20?= =?UTF-8?q?=EB=BC=88=EB=8C=80=20=E2=80=94=20=EA=B0=92=20=EC=97=86=EC=9D=B4?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=C2=B7=EA=B7=9C=EB=AA=A8=EB=A5=BC=20?= =?UTF-8?q?=EC=9E=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전제: 가격 값은 중요하지 않음. 반기마다 바뀌고 Aislo 는 자기 원천을 구독함. 중요한 것은 코드 체계·분류 깊이·명칭/규격/단위 자리·카탈로그 규모. 스키마는 암호화돼 있지 않음 — 막힌 것은 레코드 본문뿐 - JDCODE_*.BSC 12필드: 분류3단 + JDCODE(17자리) + NAME + SIZE(110자) + UNIT + EQCODE + GNCODE + TYP_STN + PSCODE + ST_NAME(표준명칭 별도) - GRPCOD_*.BSC 7필드: CUR_COD/ROT_COD/LEV 부모-자식 트리 + 형제순서 - CSTA 32필드: 재·노·경 세 성분 두 벌 + _R 계열 + 비목별 요율 암호는 오프셋별 고정 변환 - 같은 필드 안에서 같은 평문은 늘 같은 암호문 (EQCODE 57,580행 단일 암호문) - ⚠ 필드가 다르면 키가 다름. ROT_COD 가 CUR_COD 와 일치하는 비율 0.0% → 필드 안 동일성만 셀 수 있고 필드 사이는 못 이음. 트리 연결 복원 불가 - ②트랙의 STC 난독화 판정과 같은 결론이고 기준자료에서도 성립함을 확인 값을 못 읽어도 잰 것 - 자재 57,580건 전부 고유 코드인데 명칭은 1,761종뿐. 같은 이름이 규격만 달리해 평균 33건씩 갈림 — 규격 매칭이 자원 축의 실제 난관임을 수치로 보임 - 단위 59종(자재)·130종(통합). 분류 4~5단 깊이, 상위 노드 596/5,792개 - 경비·중기는 EQCODE·PSCODE·ST_NAME 을 쓰고 자재는 안 씀 - 표준시장단가는 RATE_L(72종)만 채워지고 RATE_M·RATE_S 는 빈칸 = 노무비만 요율 조정. 설치폴더의 「노임외 재료비적용」 파일명과 일치 ⇒ 가격을 못 읽는 것이 축을 세우는 데 걸림돌이 되지 않음. 이름·코드가 필요하면 평문인 COSTN.DBF 쪽에서 얻음(894개 이미 추출). 문서 29 신규, 스크립트 2개 추가. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Prk9BCHG1EMAywk9k8wegA --- .../20_분석/00_분석_요약과_읽는법.md | 7 + .../20_분석/29_암호화자료의_뼈대.md | 121 ++++++++++++++++++ .../40_스크립트/encrypted_schema_probe.py | 39 ++++++ .../40_스크립트/encrypted_structure_probe.py | 52 ++++++++ .../경쟁사 프로그램/STmate 분석/README.md | 1 + 5 files changed, 220 insertions(+) create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/29_암호화자료의_뼈대.md create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_schema_probe.py create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_structure_probe.py diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md index 8a4ff0c1..eab8feaf 100644 --- a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md @@ -35,6 +35,7 @@ | 26 편집기와 사이클식 | **`Cm` 54꼴·품셈 인자·식 편집기·낙찰율** — 계약/실행/기성 단계 발견 | (저장소 파일) | | 27 계약·실행·기성 단계 | **설계 뒤 네 단계** — 낙찰율 3갈래, 기성은 계약제잡비율, 실행 차액보정 | (저장소 파일) | | 28 변환·수량산출·식언어 | **식 변수의 대상/저장 비목** · 수량산출서 셀별명 · 조달청 변환 · 직종 106종 | (저장소 파일) | +| 29 암호화자료의 뼈대 | **값 없이 구조만** — 스키마 평문, 카탈로그 규모, 분류 4~5단, 단위 59~130종 | (저장소 파일) | > **정본은 저장소 파일이다** — `resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/`. > 위 Orca 링크는 보기용이며, 문서를 지식DB 자리로 옮기면서 주소가 한 번 바뀌었다. @@ -124,6 +125,12 @@ | 조달청 호환 | 몰랐음 | **`Conv_Jodal_ST8`·`Conv_ST8_XML` 양방향** | 28번 §3 | | 노임 직종 | 코드만 | **직종 사전 106종** 평문 | 28번 §3.1 | | 암호화 파일 | 2개 | ⚠ **3개** — `EQSYNC.DBF` 추가 | 28번 §5 | +| 암호화 자료의 **스키마** | 「못 읽음」으로만 | **전부 평문** — 필드명·형식·길이 | 29번 §1 | +| 자원 사전 구조 | 몰랐음 | **분류3단+`JDCODE`17자리+명칭+표준명칭+규격110자+단위** | 29번 §1.1 | +| 분류 트리 | 몰랐음 | **4~5단 깊이**, 부모 포인터, 형제 순서 | 29번 §1.2·§3.1 | +| 카탈로그 규모 | 건수만 | **명칭 1,761종 : 자재 57,580건** — 규격이 난관 | 29번 §3 | +| 단위 사전 | 몰랐음 | **59종(자재)·130종(통합)** | 29번 §3 | +| 표준시장단가 | 건수만 | **노무만 요율 조정** (`RATE_M`·`RATE_S` 빈칸) | 29번 §3.2 | 분석일: 2026-09-13 대상: `C:\경영정보(주)` diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/29_암호화자료의_뼈대.md b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/29_암호화자료의_뼈대.md new file mode 100644 index 00000000..3a40d344 --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/29_암호화자료의_뼈대.md @@ -0,0 +1,121 @@ +# 암호화 자료의 뼈대 — 값을 못 읽어도 구조는 잰다 + +점검일: 2026-09-13 +전제: **가격 값은 중요하지 않다.** 반기마다 바뀌고 Aislo는 자기 원천을 따로 구독한다. 중요한 것은 **코드 체계·분류 깊이·명칭/규격/단위 자리·카탈로그 규모**다. +재현 스크립트: `40_스크립트/encrypted_schema_probe.py` + +## 1. ⭐ 스키마는 암호화돼 있지 않다 + +DBF 헤더(필드 이름·형식·길이)는 **전부 평문**이다. 막힌 것은 레코드 본문뿐이다. + +### 1.1 `JDCODE_*.BSC` — 자원 코드 사전 (12필드) + +```text +TYP_1(C16) TYP_2(C10) TYP_(C11) 분류 3단 +JDCODE(C17) ⭐ 자원 코드 — 17자리 +NAME(C60) SIZE(C110) UNIT(C10) 명칭 / 규격 / 단위 +EQCODE(C11) 시설코드 +GNCODE(C11) 그룹코드 +TYP_STN(L1) 표준 여부 (논리) +PSCODE(C11) 연계 코드 +ST_NAME(C70) ⭐ 표준 명칭 (별도 칸) +``` + +**`NAME` 말고 `ST_NAME`(표준 명칭)이 따로 있다.** 물가지 표기와 표준 표기를 나눠 담는다 — 자원 축 매칭에 그대로 쓸 개념이다. + +`SIZE`가 **110자**다. 규격 문자열이 길다는 뜻이고, 매칭을 규격까지 걸면 어려운 까닭이다. + +### 1.2 `GRPCOD_*.BSC` — 분류 트리 (7필드) + +```text +TYP_1(C16) TYP_(C10) 분류 갈래 +CUR_COD(C10) 현재 노드 코드 +ROT_COD(C10) 상위 노드 코드 ← 부모 포인터 +LEV(N2) ⭐ 깊이 +NAME(C80) 분류 이름 +ORD(C5) 형제 순서 +``` + +**`CUR_COD` / `ROT_COD` / `LEV` 의 부모–자식 트리**다. 구조가 그대로 드러난다. + +### 1.3 `*.CSTA` — 표준시장단가 (32필드) + +```text +CODE(C6) · NAME(C50) · SIZE(C60) · UNIT(C10) +CODEA(C11) · JDCODE(C17) · BQCODE(C11) · EQCODE(C11) · PG_J(C12) +AAMT1~4 · MAMT1/2 · LAMT1/2 · SAMT1/2 · TAMT1/2 금액 두 벌 +MAMT1_R · LAMT1_R · SAMT1_R · MAMT2_R · LAMT2_R · SAMT2_R _R 계열 +RATE_L · RATE_M · RATE_S 비목별 요율 +TYP_C(C1) · EDT_DATE(C12) +``` + +⇒ 표준시장단가도 **재·노·경 세 성분으로 나뉘고 두 벌(1/2)**을 든다. `_R` 계열과 `RATE_*`가 따로 있는 것이 27번 §2의 「노임외 재료비로 적용 / 경비로 적용」(`ACTTYP`)과 이어진다. + +## 2. 암호는 **오프셋별 고정 변환**이다 + +같은 필드 안에서 **같은 평문은 늘 같은 암호문**이 된다. `JDCODE_M.BSC` 57,580행에서 `EQCODE`가 **단 한 가지 암호문**인 것이 증거다(= 전 행이 빈칸). + +⚠ 다만 **필드가 다르면 키가 다르다.** `GRPCOD_Z`에서 `ROT_COD`가 다른 행의 `CUR_COD`와 일치하는 비율이 **0.0%**다. 같은 코드라도 자리가 다르면 다른 암호문이 된다. + +⇒ **필드 안 동일성만 셀 수 있고, 필드 사이를 잇지는 못한다.** 트리의 부모–자식 연결은 복원 불가다. + +②트랙 `original/원가계산/STmate/STC_난독화_상태.md` 의 「오프셋별 고정 변환」 판정과 같은 결론이고, 이번에 **기준자료(BSC/CSTA)에서도 성립**함을 확인했다. + +## 3. 값을 못 읽어도 잰 것 — 카탈로그 규모 + +| 파일 | 행수 | 서로 다른 `JDCODE` | `NAME` | `SIZE` | `UNIT` | +|---|---:|---:|---:|---:|---:| +| `JDCODE_L` 노무 | 460 | **460** | 371 | 23 | — | +| `JDCODE_M` 자재 | **57,580** | **57,580** | **1,761** | 57,069 | **59** | +| `JDCODE_S` 경비 | 851 | 850 | 219 | 654 | 9 | +| `JDCODE_X` 중기 | 833 | 831 | 210 | 657 | — | +| `JDCODE_Z` 통합 | **33,927** | 33,927 | **6,170** | 18,247 | **130** | + +읽는 법 몇 가지. + +- **자재 57,580건이 전부 고유 코드**이고, **명칭은 1,761종**뿐이다. 같은 이름이 규격만 달리해 평균 **33건**씩 갈린다 — 규격 매칭이 자원 축의 실제 난관임을 수치로 보여 준다. +- **단위는 59종**(자재) · **130종**(통합). 단위 사전 크기를 미리 알 수 있다. +- `JDCODE_Z`는 `TYP_1`·`TYP_2`가 **각 6종**으로 갈린다 — 통합 사전이 6갈래 분류를 가진다. +- `JDCODE_S`·`JDCODE_X`는 `EQCODE`·`PSCODE`·`ST_NAME`이 **750~800종**으로 채워져 있다(자재는 비어 있음). **경비·중기는 시설코드와 표준명칭을 쓰고 자재는 안 쓴다.** + +### 3.1 분류 트리 규모 + +| 파일 | 행수 | `CUR_COD` 고유 | `ROT_COD` 고유 | `LEV` 값 | `NAME` 고유 | +|---|---:|---:|---:|---:|---:| +| `GRPCOD_E` | 2,539 | 2,277 | 596 | **4단** | 2,221 | +| `GRPCOD_Z` | 12,125 | 12,125 | 5,792 | **5단** | 4,295 | + +⇒ **분류가 4~5단 깊이**이고, 상위 노드가 596 / 5,792개, 한 부모의 자식이 최대 22개다. 이름은 4,295종이지만 행이 12,125이므로 **같은 이름이 여러 갈래에 걸린다.** + +### 3.2 표준시장단가 + +```text +4,921행 · CODE 4,921 고유 · NAME 488종 · SIZE 2,072종 · UNIT 22종 +BQCODE 28종 · EQCODE 89종 · PG_J 257종 · TYP_C 3종 +금액 AAMT1/TAMT1 4,719종 · MAMT 3,294 · LAMT 4,671 · SAMT 1,945 +RATE_L 72종 · LAMT1_R / LAMT2_R 각 71종 +비어 있는 필드: MAMT1_R · SAMT1_R · MAMT2_R · SAMT2_R · AAMT3 · AAMT4 · RATE_M · RATE_S · EDT_DATE +``` + +⇒ **`RATE_L`(노무 요율)만 72종으로 채워져 있고 `RATE_M`·`RATE_S`는 비어 있다.** 표준시장단가는 **노무비만 요율로 조정**한다는 뜻이고, 설치 폴더의 파일명 `표준시장[노임외 재료비적용]`·`[노임외 경비적용]`(21번 §4)과 정확히 맞는다. + +`BQCODE` 28종 = **공종 분류 28갈래**, `EQCODE` 89종 = 시설 89종. + +## 4. 이로써 Aislo 가 얻는 것 + +| 무엇 | 얻은 것 | +|---|---| +| 자원 코드 자릿수 | `JDCODE` **17자리**, 그룹 `GNCODE`·시설 `EQCODE` 각 11자리 | +| 자원 사전 구조 | 분류 3단 + 코드 + 명칭 + **표준명칭 별도** + 규격(110자) + 단위 | +| 분류 트리 | **4~5단 깊이**, 부모 포인터 방식, 형제 순서 칸 | +| 카탈로그 규모 | 자재 57,580 · 통합 33,927 · 중기 833 · 경비 851 · 노무 460 | +| 단위 사전 | **59~130종** | +| 매칭 난이도 | **명칭 1,761종 : 코드 57,580건** — 규격으로 갈린다 | +| 표준시장단가 | 재·노·경 세 성분, **노무만 요율 조정** | + +⇒ **가격을 못 읽는 것이 설계에 걸림돌이 되지 않는다.** 축을 세우는 데 필요한 것은 전부 나왔다. + +## 5. 끝내 못 얻는 것 + +`JDCODE` 값 자체 · `NAME`·`SIZE`·`UNIT` 문자열 · 가격. +⇒ **이름·코드 목록이 필요하면 프로젝트 파일 쪽에서 얻는다** — `COSTN.DBF`는 평문이고 실무 7건에서 894개를 뽑아 뒀다(`30_원자료/stmate_code_name_list.csv`). diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_schema_probe.py b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_schema_probe.py new file mode 100644 index 00000000..972169b7 --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_schema_probe.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +"""암호화 기준자료에서 '값 말고 뼈대'를 건진다 — 스키마·필드·부분 평문 여부.""" +import sys, io, struct, pathlib, collections, re +sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") +R = pathlib.Path(r"C:\경영정보(주)\System") + +def schema(b): + nrec,hlen,rlen=struct.unpack_from("=0xA1: pr+=1 + ratio.append((n, pr/max(tot,1))) + good=[n for n,r in ratio if r>0.9] + print(" 평문 비율 0.9 넘는 필드: %s" % (", ".join(good) if good else "없음")) + print(" 필드별: %s" % " ".join("%s=%.2f"%(n,r) for n,r in ratio)) + print() diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_structure_probe.py b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_structure_probe.py new file mode 100644 index 00000000..33505e9b --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/encrypted_structure_probe.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +"""암호를 풀지 않고 구조만 복원 — 같은 값은 같은 암호문이라는 성질만 쓴다. +값(이름·가격)은 끝내 모르지만 분류 트리·군집 크기·연결 관계는 나온다.""" +import sys, io, struct, pathlib, collections, hashlib +sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") +R=pathlib.Path(r"C:\경영정보(주)\System") + +def table(p): + b=p.read_bytes(); nrec,hlen,rlen=struct.unpack_from("=10))) +t1=collections.Counter(key(r["TYP_1"]) for r in jm) +t2=collections.Counter(key(r["TYP_2"]) for r in jm) +t3=collections.Counter(key(r["TYP_"]) for r in jm) +print("\n 분류 3단 고유 개수: TYP_1 %d · TYP_2 %d · TYP_ %d" % (len(t1),len(t2),len(t3))) +print(" TYP_ 군집 크기 상위 10: %s" % [c for _,c in t3.most_common(10)]) diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/README.md b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/README.md index 76536cf9..ea652a79 100644 --- a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/README.md +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/README.md @@ -67,6 +67,7 @@ | 26 | **편집기와 사이클식** — `Cm` 54꼴, 품셈 인자, 식 편집기, 낙찰율 | | 27 | **계약·실행·기성 단계** — 설계 뒤 네 단계의 계산 구조 | | 28 | **변환·수량산출·식언어** — 식 변수 대상/저장, 조달청 변환, 직종 106종 | +| 29 | **암호화자료의 뼈대** — 값 없이 구조만, 카탈로그 규모와 분류 깊이 | ## 확정된 굵직한 것