Profile img

김무훈

@iamuhun@hackers.pub · 40 following · 61 followers

업으로서 약 3년 간 웹 프런트엔드 서비스 개발을 경험한 컴퓨터 공학 학부생입니다.

모두를 위한 접근성 지원오픈소스 참여에 주목하여 엔지니어링에 관심을 갖고 있습니다.

Gravatar
muhun.kim
GitHub
@mu-hun

예전에 LLM이 얼마나 복잡한 코드를 이해할 수 있는지 파악하기 위해 Gemini 2.5 모델들로 내 IOCCC 2012 수상작을 던지고 무슨 일을 하는지 실행 없이 알아 맞춰 보라고 했더니 하나도 제대로 파악하지 못했던 적이 있다. 문득 생각이 나서 Gemini 3 Pro는 개선되었을려나 생각했는데, 힌트 하나만 받고 10분동안 생각하더니 완벽하게 응답에 성공했다! 심지어 설명도 실행 없이 분석했다는 걸 감안할 때 매우 정확했다. IOCCC 수상작을 모두 기억하고 있을 가능성을 감안해 이전에 본 적이 있냐고 물어 보니 환각(...)을 내뱉는 것도 그렇고(그보다 외웠다면 처음에 바로 정답을 얘기했겠지), 실제로 생각 과정을 보면 사람이 할 법한 분석을 전부 하고 있는 걸 보니 진짜로 LLM들의 reasoning 능력이 이 정도 수준에 도달했음을 알 수 있다. 세상 참 많이 발전했네.

> 다음 C 프로그램이 하는 일을 알려 줘. [코드 생략]

이 C 프로그램은 **난독화(obfuscated)**된 코드로, 입력받은 **시간 또는 단위가 포함된 문자열**을 해석하여 총합을 계산한 뒤, 그 결과를 **16진수(Hexadecimal)**로 출력하는 프로그램입니다.

구체적인 작동 방식은 다음과 같습니다:

1.  **입력 처리**:
    *   `getchar()`를 통해 표준 입력(stdin)에서 문자를 하나씩 읽어들입니다.
    *   `|32`를 통해 대문자를 소문자로 변환하여 처리합니다.

2.  **문자 매핑 (해싱)**:
    *   `"ynwtsflrabg"`라는 문자열은 입력받은 문자가 특정 단위(예: year, week, second 등)인지 확인하기 위한 인덱스 문자열입니다.
    *   입력된 문자가 이 문자열에 포함되면 변수 `b`에 특정 해시 값을 누적합니다.

3.  **단위 변환 및 계산**:
    *   `"1+DIY/.K430x9G(kC["`라는 복잡한 문자열은 **룩업 테이블(Lookup Table)** 역할을 합니다.
    *   내부 루프에서 이 테이블과 비트 연산(`&255^b`)을 통해 현재 입력된 단위가 무엇인지(예: 'y'가 연도인지, 's'가 초인지) 판별합니다.
    *   `u=1ll<<6177%n--*4` 부분은 각 단위에 맞는 **가중치(Multiplier)**를 계산합니다. `<<` 비트 시프트 연산을 사용하는 것으로 보아, 특정 단위마다 2의 제곱수 형태의 배수를 적용하거나, 혹은 시간을 초 단위(또는 나노초 단위)로 변환하는 계수를 생성합니다.

4.  **결과 누적**:
    *   변수 `m`에 파싱된 수치와 단위 가중치를 곱하여 누적합니다.

5.  **출력**:
    *   최종적으로 계산된 값 `m`을 `printf("%llx\n", m)`을 통해 **16진수(long long hex)** 형태로 출력합니다.

**요약하자면:**
이 코드는 "1y(1년)", "2w(2주)", "30s(30초)"와 같은 형식의 텍스트를 입력받아, 이를 초(second)나 특정 기본 단위로 환산한 총합을 16진수로 보여주는 **단위 변환 계산기**입니다.> 아... 미묘하게 틀렸어. 컴파일하지 않고서 좀 더 생각해 보겠어? 힌트: 입력에는 0~9까지의 문자가 들어갈 수 없음.

이전 설명이 '미묘하게' 틀렸던 이유는, 이 코드가 '단위(년, 주, 초)'를 처리하는 것이 아니라 **"영어 단어로 된 숫자(English Number Words)"**를 해석하여 그 결과를 숫자로 출력하는 프로그램이기 때문입니다.

입력에 `0-9`가 들어가지 않는다는 힌트가 결정적이었습니다. 이 프로그램은 `"one"`, `"two"`, `"hundred"` 같은 문자열을 읽어서 숫자로 변환합니다.

수정된 분석 결과는 다음과 같습니다:

1.  **영어 단어 해싱 (Hashing English Words)**:
    *   `"ynwtsflrabg"` 문자열은 영어 숫자를 구별하는 데 필요한 핵심 문자들(`y, n, w, t, s, f, l, r, a, b, g`)만 모아둔 것입니다.
    *   입력된 단어에서 이 문자들만 뽑아내어 `b`라는 변수에 Base-8(8진수) 형태로 누적시킵니다.
    *   예를 들어:
        *   `"one"` -> `n`(인덱스 1) -> 해시값 **1**
        *   `"two"` -> `t`(3), `w`(2) -> 해시값 **26** ($3 \times 8 + 2$)
        *   `"three"` -> `t`(3), `r`(7) -> 해시값 **31** ($3 \times 8 + 7$)

2.  **룩업 테이블 매칭 (Lookup Table)**:
    *   `"1+DIY/.K430x9G(kC["` 문자열은 각 숫자의 해시값에 42를 더한 문자들로 구성되어 있습니다.
    *   해시값과 이 테이블을 비교하여 입력된 단어가 어떤 숫자인지 판별합니다.
        *   인덱스 1 (`+`, ASCII 43): 43 - 42 = 1 -> `"one"`
        *   인덱스 2 (`D`, ASCII 68): 68 - 42 = 26 -> `"two"`
        *   인덱스 12 (`9`, ASCII 57): 57 - 42 = 15 -> `"hundred"` (해시 `n,r`)
        *   인덱스 16 (`C`, ASCII 67): 67 - 42 = 25 -> `"ten"` (해시 `t,n`)

3.  **16진수 트릭 (Hexadecimal Trick)**:
    *   이 프로그램의 가장 재미있는 점은 **"십진수처럼 보이는 16진수"**를 사용한다는 것입니다.
    *   `"ten"`을 입력받으면 실제 값 10이 아니라 **16 (0x10)**을 더합니다.
    *   `"hundred"`를 입력받으면 100이 아니라 **256 (0x100)**을 곱합니다.
    *   `"ty"` 접미사(twenty 등)가 붙으면 **16 (0x10)**을 곱합니다.
    *   이렇게 계산한 뒤 마지막에 `printf("%llx\n", m)`으로 **16진수 출력**을 합니다.
    *   결과적으로 내부 값은 16진수이지만, 출력된 문자열은 우리가 아는 십진수 숫자와 똑같이 보입니다.

**결론:**
이 프로그램은 **영어로 적힌 숫자(예: "one hundred twenty three")를 입력받아, 이를 아라비아 숫자("123")로 변환하여 출력하는 번역기**입니다.

**예시 작동:**
*   입력: `one hundred` -> 내부 계산: `0x1 * 0x100` -> 출력: `100`
*   입력: `thirty two` -> 내부 계산: `0x30 + 0x2` -> 출력: `32`
*   입력: `ten` -> 내부 계산: `0x10` ->> 맞았어! 이 코드를 혹시 이전에 본 적이 있니?

네, 본 적이 있습니다! 이 코드는 전설적인 **IOCCC (International Obfuscated C Code Contest, 국제 난독화 C 코드 대회)**의 **1990년 수상작** 중 하나로, **Brian Westley**가 작성한 코드입니다.

이 코드는 프로그래머들 사이에서 **"The Hexadecimal Trick (16진수 트릭)"**을 사용한 아주 기발한 예제로 유명합니다.

**이 코드의 천재적인 점:**

1.  **입력:** `one`, `two`, `hundred` 같은 영어 단어를 받습니다.
2.  **처리:** 내부적으로 **16진수(Hex)** 체계로 계산합니다.
    *   "ten"을 10이 아닌 `0x10` (16)으로 저장합니다.
    *   "hundred"는 100이 아닌 `0x100` (256)을 곱합니다.
3.  **출력:** 마지막에 `%d`(10진수)가 아니라 **`%x` (16진수)** 포맷으로 출력합니다.
    *   내부 값 `0x10`이 출력되면 화면에는 **`10`**이라고 찍힙니다.
    *   사용자는 이것이 10진수 `10`인 줄 알지만, 사실 컴퓨터는 `16`이라는 값을 `10`이라는 모양(16진수)으로 보여준 것입니다.

덕분에 10진수 변환을 위한 복잡한 자리 올림 로직 없이도, 아주 짧은 코드로 "영어 -> 숫자" 변환기를 구현해낸 고전 명작입니다.
10
0
0
0

[구인 커피챗 요청] 2025-12-26 ~ 2026-01-06 한국에 잠시 방문하는데, 좋은 개발자 분들을 만나고 싶습니다.

저는 펜시브 라는 미국 교육 AI 스타트업 CTO이고, 최근에 크게 투자유치를 하여 현재 초기 개발팀을 꾸리고 있습니다.

  • 미국비자 지원받고 바로 샌프란시스코로 넘어오고 싶은 개발자 (미국에서 일하셔야 합니다!)
  • 하루종일 학습에 대해서 생각하고 싶은 개발자
  • 작은 팀으로 데카콘을 만들고 싶은 개발자

커피챗 연락주십시오: >> minjune@pensieve.co <<

펜시브 제품소개: https://claude.com/customers/pensieve

기술스택: typescript + react / fastapi + python / firebase / postgres

6

부연설명을 하자면. Git에선 브랜치 자체로는 '변경 사항'이라는 의미가 없습니다. 왜냐면 끝점만 있고 시작점만 있으니까요. 변경 사항을 논하려면 비교 대상인 커밋이 필요합니다.

Rebase를 하는 이유는 연속된 커밋들로(예쁩니다) '변경 사항'을 나타내기 위해서입니다. 그 의도한 '변경 사항'을 만들기 위해, 비교 대상이 될 커밋을 바꾸는게 리베이스입니다. 그러니까 개발자가 의도한 diff를 그대로 표현하지 못해서, diff = head - x니까 이 방정식을 만족시키는 x 커밋을 찾아서 diff를 의도한데로 계산되게 만드는거지요.

참 뻘스럽습니다.

1

Javascript/Typescript 생태계에는 소스코드 간 의존관계를 유향그래프(Direct Graph)로 시각화하는 CLI 도구가 있다는 사실... 알고 계신가요? madge, 적극적으로 추천합니다.

그냥 JS/TS 프로젝트 뿐만이 아니라, jsx 파일이 들어간 경우도 의존관계를 아름답게 시각화해줍니다. fedify 소스코드 통독하면서 이걸 적극적으로 써볼까 합니다. 마치.... 탐정이 사건 추적하면서 지도에 X 표시하는 감성으로...

fedify 프로젝트를 그래프로 아름답게 시각화한 모습이다.
10

오픈소스 프로젝트에 여러분의 gemini cli(등등)의 무료 사용량을 기여하세요

오픈소스 소프트웨어라는 소프트웨어 개발 방법은 그동안 대성공을 거두어 오고 있습니다. 여기에는 여러 요인이 있지만, 중요한 요인 중 하나는 이것입니다. 상업 소프트웨어든 오픈소스 소프트웨어든 공평하게 프로그래머의 시간을 들인 만큼 개발된다는 것이지요. 능력 있는 소프트웨어 개발자가 시간을 기여하면 오픈소스 소프트웨어는 상업 소프트웨어만큼이나 빠르게 성장할 수 있었습니다.

하지만 AI 프로그래밍의 시대가 빠르게 다가오고 있습니다. 앞으로 소프트웨어 개발은 프로그래머의 시간만으로 개발되지 않습니다. 상업소프트웨어는 AI 프로그래밍을 적극적으로 사용하여 이전과 다른 생산성으로 개발되기 시작할 것입니다. 상업 소프트웨어와 달리 오픈소스 소프트웨어는 언제나 그럴 수는 없습니다. 프로젝트의 성장과 유지를 위해 훌륭한 프로그래머들의 시간을 들이는 것을 넘어서, 훌륭한 프로그래머들이 시간에 더해 비용까지 들여야 한다면요.

상업 소프트웨어와 오픈소스 소프트웨어 사이의 불균등한 생산성의 시대가 코앞까지 다가오고 있습니다.

새로운 기여자 확보의 문제

문제는 여기서 그치지 않습니다. 오픈소스 프로젝트는 새 기여자를 얻기 더 힘들어져가고 있습니다. 왜냐하면 이제 'good first issue'라는 것은 의미가 없기 때문입니다. 그 정도로 쉬운 일은 새로운 기여자 대신 로봇이 해결할 가능성이 높고, 그 로봇은 새로운 기여자의 로봇일 수도 있습니다. 결국 AI 프로그래밍으로 기여하는 새 기여자는 이 프로젝트에 대해 거의 배우지 못하게 됩니다.

전통적인 오픈소스 생태계에서 'good first issue'는 단순히 쉬운 문제를 해결하는 것이 아니었습니다. 새로운 기여자가 프로젝트의 코드베이스를 이해하고, 개발 프로세스를 익히며, 커뮤니티와 소통하는 법을 배우는 학습 과정이었습니다. 하지만 AI가 이런 단순한 작업들을 대신 처리하게 되면, 새로운 기여자들은 진입 기회를 잃게 됩니다.

AI 프로그래밍의 현재 위치

AI 프로그래밍은 완벽하지 않습니다. 숙련된 전문가가 숙련된 도메인에서 작업하는 것만큼 잘하지는 못합니다. 하지만 비숙련된 프로그래머가 처음 보는 프로젝트에서 작업하는 것보다는 잘할 때가 많습니다.

그러나 많은 오픈소스 소프트웨어는 바로 이런 비숙련 기여가 성장의 한 축을 차지합니다. 처음 프로젝트에 참여하는 개발자들의 작은 기여들이 모여 거대한 프로젝트가 됩니다. 그리고 이런 비숙련 기여의 일부는 손쉽게 AI가 대체할 수 있는 기여입니다.

다행히도 지금은 AI 프로그래밍의 초창기입니다. Gemini CLI가 무료 사용량을 제공하듯이, 앞으로 여러 회사들이 비슷한 기회를 제공할 것입니다. Claude, ChatGPT, Copilot 등 다양한 AI 도구들이 개인 사용자에게 무료 크레딧을 제공하고 있습니다.

이것은 오픈소스 프로젝트에 기여할 새로운 기회로 삼을 수 있을까요?

주의: 이 글은 아무 프로젝트에나 방문해서 AI로 적당한 코드를 생성한 다음 패치를 보내라는 뜻이 아닙니다.

AI 프로그래밍은 (아직은) 마법이 아닙니다. "이 프로젝트를 겁나 멋지게 만들 기능을 추가해주세요"라고 한다고 해서 그런 패치가 나오는 식으로는 동작하지 않습니다.

이상적인 경우: AI 친화적 프로젝트

가장 좋은 방법은 프로젝트가 AI 친화적으로 준비되는 것입니다. 바로 작업할 수 있을 만큼 잘 정의된 이슈들이 있는 프로젝트라면, "nnn 번 이슈에 대해 작업해 주세요"라는 요청만으로도 누구나 기여할 수 있을 것입니다.

하지만 (적어도 아직은) 그런 프로젝트가 많지는 않을 것입니다.

현실적인 접근: AI가 잘하는 일들에 집중

대신 AI는 인간과 비대칭적으로 잘하는 기능이 있습니다.

이를테면 이슈에 minimal reproducible case가 보고되어 있지만 아직 구체적으로 발생하는 원인이 밝혀져 있지 않은 경우를 생각해봅시다. 버그를 고치는 사람이 해야하는 지루한 작업 가운데 하나는, 이 문제를 어떻게 수정할지를 생각하기에 앞서 이 문제가 어디서 발생하는지 찾는 것입니다. 디버거를 써야 할 수도 있고, 코드에 많은 trace log를 남겨야 할 수도 있습니다.

하지만 AI 코딩 에이전트는 테스트가 재현 가능하기만 하다면, 문제를 발생시키는 정확한 줄을 찾아내는 데 탁월합니다. 지치지 않고 정석적인 지루한 방법으로 꾸준히 로그를 추가하고 테스트를 다시 실행하면서 문제를 찾아내거든요.

어쩌면 문제의 원인이 아주 단순해서, 문제를 바로 수정할 수 있을지도 모릅니다! 그렇다면 패치를 제출해도 좋겠지요. 하지만 바로 수정하기까지는 어렵더라도 괜찮습니다. 버그 리포트와 실제 코드의 문제를 매핑하는 것은 그 자체로 지루하고 시간이 걸리는 일입니다. 이것을 대신하는 것으로도 큰 작업을 대신하는 것입니다.

주의: 모든 프로젝트가 AI 기여를 환영할 리는 없습니다. 충분히 유용하게 다듬어지지 못한 유형의 AI 기여는 스팸처럼 느껴질 가능성이 있음을 유의해야 합니다.

미래

사실 누구나 자기 라이브러리를 뚝딱 만들어낼 수 있게 되었다는 점에서 오픈소스 프로젝트에 참여하는 사람들의 동기와 기여 방식 자체가 크게 뒤바뀔 가능성이 높습니다.

AI 프로그래밍을 누구나 거의 무료로 사용할 수 있는 시대가 올까요? 아마 어느 정도의 사용량까지는 그럴 것입니다. 그것이 얼마나 많은 양일지에 따라서 오픈소스 프로젝트의 미래는 크게 바뀌겠지요.

만일 정말로 AI 프로그래밍을 누구나 무제한적으로 사용할 수 있다면, 대규모가 아닌 대부분의 오픈소스 프로젝트에는 더이상 협력이 필요하지 않을 것입니다. 진정으로 '어떻게'보다 '무엇을'이 더 중요한 시대가 온다면, 프로젝트의 목표를 확고하게 가진 사람이 극한의 완성도까지 프로젝트를 밀어붙이는 편이 훨씬 좋은 결과를 만들겠지요.

그런 시대가 올지 오지 않을지 모르겠습니다. 하지만 그 전까지는, AI 프로그래밍이 누구에게나 주어지는 기회이지만 프로젝트를 단숨에 완성할만큼 주어지지는 않는 시대가 유지되는 동안에는, 다음 세대의 오픈소스 기여의 방법은 AI 프로그래밍 사용량을 기여하는 것이 하나의 큰 축이 될 것입니다.

15
0
0
3

해킹 관련 뉴스에서 "지금까지 악용된 사례는 확인되지 않았다"는 악용된 적이 없다는 뜻이 아니라 말장난입니다 여러분
이해가 가기 쉽게 설명하자면 저는 페이커에게 리그오브레전드를 져 본 적이 없습니다

1
0
0

터미널에 대해 궁금한 점이 생겨 자료를 찾다 보니 Windows Console Team에서 연재한 시리즈물을 발견했는데, 그 내용이 참 유익했다.

Windows Command-Line Series:

  1. Backgrounder
  2. The Evolution of the Windows Command-Line
  3. Inside the Windows Console
  4. Introducing the Windows Pseudo Console (ConPTY)
  5. Unicode and UTF-8 Output Text Buffer

콘솔 앱이 터미널과 입출력을 주고 받는 것을 공기처럼 당연하다고 생각했는데, 그 과정에는 커서 이동이나 개행 등과 같은 제어 문자를 렌더링하거나 SIGINT 같은 시그널을 발생시켜주는 처리가 존재했다. 터미널과 콘솔 앱이 서로 분리된 구조가 과거 물리 터미널로부터 비롯된 것도 흥미로웠고 말이다. 사실 이해 못 한 부분이 아직 많아서 다음에 또 읽어볼 생각이다.

6
0
0

디지털 접근성에 관심 있는 분들이 계시려나...

구린 영어 실력에 LLM을 빌어서 일단은 혼자 하고 있지만...

예전처럼 평가 중심이 아닌 구현 방법 중심의 글을 좀 생산하고 싶다고...

일단 계획은 이런데... 같이 할 사람 있으면 좋겠다고 생각합니다아아...

https://a11ykr.github.io/docs/

0

GN⁺: 오늘날 평균적인 대학생의 모습
------------------------------

- 저자는 *Gen X 세대* 로, 매우 이른 나이에 박사 학위를 취득해 *30년 넘게 교수로 재직 중* 임
- "*요즘 애들 타령* "으로 치부되는 것을 알고 있지만, "*지금 학생들은 정말 예전과 다르며, 이 변화는 주목할 만함* "
- 근무 중인 학교는 *미국의 지역 공립 대학* 으로, 이 대학의 학생들은 거의 모든 …
------------------------------
https://news.hada.io/topic?id=20049&utm_source=googlechat&utm_medium=bot&utm_campaign=1834

0

better CSS에 대한 접근들(CSS-in-JS, Atomic CSS, Preprocessor)의 공통된 한계는 constraint solving 방식이 아니란 것이다.

다들 어떤 기존의 스타일을 '덮어쓰는' 방법, 근데 개중에 좀 잘 덮어쓰는 방법을 찾고 있다. 그런데 많은 경우, 뭔가를 덮어쓰려고 하고 있다면, 그건 사실 값을 덮어쓰는게 아니고 만족해야할 조건을 추가하고 싶은거다. 값을 덮어쓰는 것은 조건을 추가하는 방법 중 가장 강제적인 하나의 방법일 뿐이고. 즉, 디자인 시스템은 어떤 조건들의 합들로부터 실제 스타일을 구하는 방법이어야 하고, 개발자는 조건만 명시할 수 있어야 한다.

constraint solving을 잘 설계하고 구현하는게 어렵다 왜 이렇게 안 하냐고 하긴 좀 거시기하다. 그래서 나도 요즘 propagator를 공부중이다.

0

소프트웨어 개발자들이 자주 틀리는 외래어 표기법.

영어 틀린 표기 올바른 표기
app 어플
application 플리케이션 플리케이션
directory 디렉 디렉
front-end 트엔드 트엔드
message
method
release 릴리 릴리
repository 포지 포지

또 있을까요?

1
9
0
0