<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://encryh.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://encryh.github.io/" rel="alternate" type="text/html" /><updated>2026-03-25T19:29:55+09:00</updated><id>https://encryh.github.io/feed.xml</id><title type="html">EncryH.blog</title><subtitle>보안 학습을 기록하는 블로그</subtitle><author><name>Kang Humin</name></author><entry><title type="html">[Data structure] C로 구현한 단순 연결 리스트 삽입</title><link href="https://encryh.github.io/c/LinkedListInsert/" rel="alternate" type="text/html" title="[Data structure] C로 구현한 단순 연결 리스트 삽입" /><published>2026-03-25T00:00:00+09:00</published><updated>2026-03-25T00:00:00+09:00</updated><id>https://encryh.github.io/c/LinkedListInsert</id><content type="html" xml:base="https://encryh.github.io/c/LinkedListInsert/"><![CDATA[<h1 id="1-프로젝트-개요">1. 프로젝트 개요</h1>
<p>자료구조 과목에서 C 언어 기반으로 단순 연결 리스트(Singly Linked List)를 구현하면서 세 가지 삽입 연산을 정리했다.</p>

<p>이번 실습에서 구현한 삽입 기능은 다음과 같다.</p>

<ol>
  <li>첫 노드 삽입</li>
  <li>마지막 노드 삽입</li>
  <li>오름차순을 유지한 상태에서 삽입</li>
</ol>

<p>배열 기반 선형 리스트와 달리 연결 리스트는 포인터를 이용해 노드를 연결하므로, 특정 위치에 원소를 삽입할 때 전체 데이터를 한 칸씩 밀어내지 않아도 된다는 특징이 있다.</p>

<h1 id="2-구조체-설계">2. 구조체 설계</h1>
<p>연결 리스트는 노드(Node)와 리스트(List) 구조체로 구성했다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="k">struct</span> <span class="n">Node</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">val</span><span class="p">;</span>
    <span class="k">struct</span> <span class="n">Node</span><span class="o">*</span> <span class="n">next</span><span class="p">;</span>
<span class="p">}</span> <span class="n">Node</span><span class="p">;</span>

<span class="k">typedef</span> <span class="k">struct</span> <span class="n">List</span> <span class="p">{</span>
    <span class="n">Node</span><span class="o">*</span> <span class="n">head</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span> <span class="n">List</span><span class="p">;</span>
</code></pre></div></div>

<p>각 구조체의 역할은 다음과 같다.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">Node</code>는 실제 데이터(<code class="language-plaintext highlighter-rouge">val</code>)와 다음 노드를 가리키는 포인터(<code class="language-plaintext highlighter-rouge">next</code>)를 가진다.</li>
  <li><code class="language-plaintext highlighter-rouge">List</code>는 연결 리스트의 시작 주소인 <code class="language-plaintext highlighter-rouge">head</code>와 전체 노드 개수인 <code class="language-plaintext highlighter-rouge">node_cnt</code>를 저장한다.</li>
</ul>

<h1 id="3-초기화와-노드-생성">3. 초기화와 노드 생성</h1>
<p>리스트를 사용하기 전에 반드시 초기화해야 하며, 노드는 동적 할당을 통해 생성한다. 아래 코드는 과제에서 사용한 원본 코드 그대로이다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 초기화</span>
<span class="kt">void</span> <span class="nf">list_init</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">Node</span><span class="o">*</span> <span class="nf">createNode</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
	<span class="kt">int</span> <span class="n">num</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">num</span> <span class="o">=</span> <span class="n">rand</span><span class="p">()</span> <span class="o">%</span> <span class="mi">100</span><span class="p">;</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">New_node</span> <span class="o">=</span> <span class="p">(</span><span class="n">Node</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">Node</span><span class="p">));</span>
	<span class="n">New_node</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">=</span> <span class="n">num</span><span class="p">;</span>
	<span class="n">New_node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>

	<span class="k">return</span> <span class="n">New_node</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이 구현에서는 <code class="language-plaintext highlighter-rouge">rand()</code>를 이용해 0부터 99 사이의 정수를 만들고, 이를 새 노드의 값으로 저장했다.</p>

<h1 id="4-리스트-출력">4. 리스트 출력</h1>
<p>삽입 결과가 잘 반영되는지 확인하기 위해 리스트 전체를 순회하며 출력하는 함수를 사용했다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">list_print</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">list</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">printf</span><span class="p">(</span><span class="s">"list is not exist!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
		<span class="k">return</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="n">Node</span><span class="o">*</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

	<span class="k">while</span> <span class="p">(</span><span class="n">tmp</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">printf</span><span class="p">(</span><span class="s">"%2d - "</span><span class="p">,</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">);</span>
		<span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이 함수는 <code class="language-plaintext highlighter-rouge">head</code>부터 시작해서 <code class="language-plaintext highlighter-rouge">next</code>를 따라가며 모든 노드의 값을 출력한다. 연결 리스트는 배열처럼 인덱스로 접근할 수 없기 때문에 이런 순회 과정이 기본이 된다.</p>

<h1 id="5-삽입-연산-구현">5. 삽입 연산 구현</h1>
<h2 id="5-1-첫-노드-삽입">5-1. 첫 노드 삽입</h2>
<p>가장 앞에 노드를 삽입하는 방식은 가장 단순하다. 새 노드의 <code class="language-plaintext highlighter-rouge">next</code>가 기존 <code class="language-plaintext highlighter-rouge">head</code>를 가리키게 한 뒤, <code class="language-plaintext highlighter-rouge">head</code>를 새 노드로 바꾸면 된다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">list_append_first</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">,</span> <span class="n">Node</span><span class="o">*</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">New_node</span><span class="p">;</span>
	<span class="c1">//New_node = (Node*)malloc(sizeof(Node));</span>
	<span class="c1">// New_node-&gt;val = list;</span>

	<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>

	<span class="c1">// 카운트</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이 방식은 별도의 탐색이 필요하지 않기 때문에 시간 복잡도는 <code class="language-plaintext highlighter-rouge">O(1)</code>이다.</p>

<h2 id="5-2-마지막-노드-삽입">5-2. 마지막 노드 삽입</h2>
<p>마지막 삽입은 리스트 끝까지 이동한 뒤 마지막 노드의 <code class="language-plaintext highlighter-rouge">next</code>에 새 노드를 연결해야 한다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">list_append_last</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">,</span> <span class="n">Node</span><span class="o">*</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">tmp</span><span class="p">;</span>
	<span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

	<span class="k">if</span> <span class="p">(</span><span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
		<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
		<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
		<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="p">{</span>
		<span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

		<span class="k">while</span> <span class="p">(</span><span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
			<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
		<span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>리스트가 비어 있지 않은 경우 마지막 노드를 찾기 위해 전체를 순회해야 하므로 시간 복잡도는 <code class="language-plaintext highlighter-rouge">O(n)</code>이다.</p>

<h2 id="5-3-오름차순-유지-삽입">5-3. 오름차순 유지 삽입</h2>
<p>정렬된 상태를 유지하면서 삽입하려면 새 노드가 들어갈 위치를 찾아야 한다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">list_append_ordered</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">,</span> <span class="n">Node</span><span class="o">*</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">tmp</span><span class="p">;</span>
	<span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

	<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tmp</span> <span class="o">||</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
		<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="p">{</span>
		<span class="k">while</span> <span class="p">(</span><span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">&amp;&amp;</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span>
			<span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>

		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
		<span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>

	<span class="p">}</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이 함수는 다음 두 가지 경우로 나누어 생각할 수 있다.</p>

<ol>
  <li>리스트가 비어 있거나 새 값이 가장 작은 경우</li>
  <li>중간 또는 마지막 위치에 삽입해야 하는 경우</li>
</ol>

<p>두 번째 경우에는 <code class="language-plaintext highlighter-rouge">tmp-&gt;next-&gt;val</code>과 새 노드 값을 비교하면서 삽입 지점을 찾는다. 위치를 찾은 뒤에는 포인터 두 개만 변경하면 되므로 연결 자체는 간단하지만, 위치 탐색 때문에 시간 복잡도는 <code class="language-plaintext highlighter-rouge">O(n)</code>이다.</p>

<h1 id="6-전체-코드">6. 전체 코드</h1>
<p>아래는 과제에서 사용한 원본 코드 전체이다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define _CRT_SECURE_NO_WARNINGS
#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;time.h&gt;</span><span class="cp">
</span>
<span class="c1">// 구조체 정의</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">Node</span> <span class="p">{</span>
	<span class="kt">int</span> <span class="n">val</span><span class="p">;</span>
	<span class="k">struct</span> <span class="n">Node</span><span class="o">*</span> <span class="n">next</span><span class="p">;</span>
<span class="p">}</span> <span class="n">Node</span><span class="p">;</span>

<span class="k">typedef</span> <span class="k">struct</span> <span class="n">List</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">head</span><span class="p">;</span>
	<span class="kt">int</span> <span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span> <span class="n">List</span><span class="p">;</span>

<span class="c1">// 초기화</span>
<span class="kt">void</span> <span class="nf">list_init</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">Node</span><span class="o">*</span> <span class="nf">createNode</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
	<span class="kt">int</span> <span class="n">num</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">num</span> <span class="o">=</span> <span class="n">rand</span><span class="p">()</span> <span class="o">%</span> <span class="mi">100</span><span class="p">;</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">New_node</span> <span class="o">=</span> <span class="p">(</span><span class="n">Node</span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">Node</span><span class="p">));</span>
	<span class="n">New_node</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">=</span> <span class="n">num</span><span class="p">;</span>
	<span class="n">New_node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>

	<span class="k">return</span> <span class="n">New_node</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">list_print</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">list</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">printf</span><span class="p">(</span><span class="s">"list is not exist!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
		<span class="k">return</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="n">Node</span><span class="o">*</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

	<span class="k">while</span> <span class="p">(</span><span class="n">tmp</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">printf</span><span class="p">(</span><span class="s">"%2d - "</span><span class="p">,</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">);</span>
		<span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// 첫 지점 삽입</span>
<span class="kt">int</span> <span class="nf">list_append_first</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">,</span> <span class="n">Node</span><span class="o">*</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">New_node</span><span class="p">;</span>
	<span class="c1">//New_node = (Node*)malloc(sizeof(Node));</span>
	<span class="c1">// New_node-&gt;val = list;</span>

	<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>

	<span class="c1">// 카운트</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// 마지막 지점 삽입</span>
<span class="kt">int</span> <span class="nf">list_append_last</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">,</span> <span class="n">Node</span><span class="o">*</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">tmp</span><span class="p">;</span>
	<span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

	<span class="k">if</span> <span class="p">(</span><span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
		<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
		<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
		<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="p">{</span>
		<span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

		<span class="k">while</span> <span class="p">(</span><span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
			<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
		<span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// 오름차순을 유지한 상태로 새로운 노드 값을 삽입</span>
<span class="kt">int</span> <span class="nf">list_append_ordered</span><span class="p">(</span><span class="n">List</span><span class="o">*</span> <span class="n">list</span><span class="p">,</span> <span class="n">Node</span><span class="o">*</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">Node</span><span class="o">*</span> <span class="n">tmp</span><span class="p">;</span>
	<span class="n">tmp</span> <span class="o">=</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span><span class="p">;</span>

	<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tmp</span> <span class="o">||</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
		<span class="n">list</span><span class="o">-&gt;</span><span class="n">head</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="p">{</span>
		<span class="k">while</span> <span class="p">(</span><span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">&amp;&amp;</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="o">-&gt;</span><span class="n">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span>
			<span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>

		<span class="n">node</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
		<span class="n">tmp</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">node</span><span class="p">;</span>

	<span class="p">}</span>
	<span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="o">++</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">list</span><span class="o">-&gt;</span><span class="n">node_cnt</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

	<span class="n">srand</span><span class="p">(</span><span class="n">time</span><span class="p">(</span><span class="nb">NULL</span><span class="p">));</span>

	<span class="n">List</span> <span class="n">list</span><span class="p">;</span>
	<span class="n">list_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">list</span><span class="p">);</span>

	<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">Node</span><span class="o">*</span> <span class="n">node</span> <span class="o">=</span> <span class="n">createNode</span><span class="p">();</span>

		<span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="n">list_append_ordered</span><span class="p">(</span><span class="o">&amp;</span><span class="n">list</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
		
		<span class="n">printf</span><span class="p">(</span><span class="s">"val : %d, ret : %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">,</span> <span class="n">ret</span><span class="p">);</span>
		

		<span class="n">list_print</span><span class="p">(</span><span class="o">&amp;</span><span class="n">list</span><span class="p">);</span>
	<span class="p">}</span>
	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h1 id="7-시간-복잡도-정리">7. 시간 복잡도 정리</h1>
<p>각 삽입 연산의 시간 복잡도는 다음과 같다.</p>

<ul>
  <li>첫 노드 삽입: <code class="language-plaintext highlighter-rouge">O(1)</code></li>
  <li>마지막 노드 삽입: <code class="language-plaintext highlighter-rouge">O(n)</code></li>
  <li>오름차순 유지 삽입: <code class="language-plaintext highlighter-rouge">O(n)</code></li>
</ul>

<p>즉, 연결 리스트는 앞쪽 삽입에는 매우 효율적이지만 마지막 삽입이나 정렬 삽입처럼 탐색이 필요한 경우에는 선형 시간이 필요하다.</p>

<h1 id="8-느낀-점과-개선-방향">8. 느낀 점과 개선 방향</h1>
<p>이번 구현을 통해 단순 연결 리스트에서 핵심은 데이터 자체보다도 포인터 연결 순서를 정확히 유지하는 것이라는 점을 확인할 수 있었다.</p>

<p>특히 오름차순 삽입은 단순히 값을 넣는 것이 아니라 삽입 위치를 먼저 찾고, 이전 노드와 다음 노드 사이에 새 노드를 안전하게 연결해야 하므로 포인터 조작에 대한 이해가 중요했다.</p>

<p>추가로 보완할 수 있는 부분은 다음과 같다.</p>

<ul>
  <li>프로그램 종료 전 전체 노드를 <code class="language-plaintext highlighter-rouge">free()</code>하는 메모리 해제 함수 추가</li>
  <li>사용자가 직접 삽입 방식을 선택할 수 있는 메뉴 기반 프로그램으로 확장</li>
  <li><code class="language-plaintext highlighter-rouge">tail</code> 포인터를 추가해 마지막 삽입 시간을 <code class="language-plaintext highlighter-rouge">O(1)</code>로 개선</li>
</ul>

<h1 id="9-정리">9. 정리</h1>
<p>이번 실습에서는 C 언어로 단순 연결 리스트를 직접 구현하고, 첫 삽입, 마지막 삽입, 오름차순 유지 삽입까지 단계적으로 작성했다.</p>

<p>배열 기반 자료구조와 비교했을 때 연결 리스트는 삽입 시 데이터 이동이 필요 없다는 장점이 있지만, 원하는 위치를 찾기 위해 순차 탐색이 필요하다는 점도 함께 확인할 수 있었다.</p>

<p>자료구조 수업에서 배운 연결 리스트의 기본 원리를 코드로 직접 구현해 보면서, 포인터 기반 자료구조를 다루는 감각을 익힐 수 있었던 실습이었다.</p>]]></content><author><name>Kang Humin</name></author><category term="C" /><category term="C" /><category term="Data structure" /><category term="Linked List" /><summary type="html"><![CDATA[1. 프로젝트 개요 자료구조 과목에서 C 언어 기반으로 단순 연결 리스트(Singly Linked List)를 구현하면서 세 가지 삽입 연산을 정리했다.]]></summary></entry><entry><title type="html">[Linux] GCC를 이용한 C 프로그램 컴파일 과정 실습</title><link href="https://encryh.github.io/c/LinuxC/" rel="alternate" type="text/html" title="[Linux] GCC를 이용한 C 프로그램 컴파일 과정 실습" /><published>2026-01-01T00:00:00+09:00</published><updated>2026-01-01T00:00:00+09:00</updated><id>https://encryh.github.io/c/LinuxC</id><content type="html" xml:base="https://encryh.github.io/c/LinuxC/"><![CDATA[<h1 id="1-gcc란-무엇인가">1. GCC란 무엇인가</h1>
<p>GCC(GNU Compiler Collection)는 C, C++, Java 등 다양한 프로그래밍 언어를 컴파일할 수 있는 컴파일러이다.</p>

<p>리눅스 환경에서 C 프로그램을 컴파일할 때 가장 널리 사용되며, GCC를 이용하면 C 소스 코드를 컴파일하여 실행 가능한 프로그램으로 변환할 수 있다.</p>

<h1 id="2-c-소스-파일-생성">2. C 소스 파일 생성</h1>
<p>리눅스에서는 터미널을 이용하여 C 소스 파일을 생성할 수 있다.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vi</span> <span class="n">hello</span><span class="p">.</span><span class="n">c</span>
</code></pre></div></div>
<p>위 명령어를 실행하면 vi 편집기가 실행되는데 hello.c 파일을 생성하거나 열 수 있다.</p>

<h1 id="3-vi-편집기를-이용한-코드-작성">3. vi 편집기를 이용한 코드 작성</h1>
<p>vi 편집기에서 코드를 작성하기 위해서는 Insert 모드로 전환해야 하는데, <code class="language-plaintext highlighter-rouge">i</code>키를 누르면 입력모드로 전환된다.</p>

<p>이후 다음과 같이 C 코드를 작성한다.</p>

<p><img src="/image/2026-01-01-LinuxC/helloc.png" alt="helloc" /></p>

<p>코드 작성이 끝나면 ESC 키를 눌러 명령 모드로 전환한 뒤 <code class="language-plaintext highlighter-rouge">:wq</code>  명령어로 저장한다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">w</span> <span class="err">→</span> <span class="n">write</span> <span class="p">(</span><span class="err">저장</span><span class="p">)</span>
<span class="n">q</span> <span class="err">→</span> <span class="n">quit</span> <span class="p">(</span><span class="err">종료</span><span class="p">)</span>
</code></pre></div></div>

<h1 id="4-gcc를-이용한-컴파일">4. GCC를 이용한 컴파일</h1>
<p>작성한 C 프로그램을 GCC로 컴파일한다.</p>

<p><img src="/image/2026-01-01-LinuxC/a.out.png" alt="a.out" /></p>

<p>컴파일이 완료되면 기본적으로 <code class="language-plaintext highlighter-rouge">a.out</code> 실행 파일이 생성된다.</p>

<h1 id="5-프로그램-실행">5. 프로그램 실행</h1>
<p>생성된 실행 파일을 <code class="language-plaintext highlighter-rouge">./</code> 명령어를 사용해서 실행한다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">리눅스에서</span> <span class="p">.</span><span class="o">/</span> <span class="err">는</span> <span class="err">현재</span> <span class="err">디렉터리</span><span class="p">(</span><span class="n">Current</span> <span class="n">Directory</span><span class="p">)</span> <span class="err">를</span> <span class="err">의미한다</span><span class="p">.</span> <span class="err">즉</span><span class="p">,</span> <span class="err">현재</span> <span class="err">디렉터리에</span> <span class="err">있는</span> <span class="err">실행</span> <span class="err">파일을</span> <span class="err">실행하라는</span> <span class="err">의미이다</span><span class="p">.</span>
</code></pre></div></div>

<p><img src="/image/2026-01-01-LinuxC/실행결과출력.png" alt="실행결과출력" /></p>

<p>위 사진처럼 <code class="language-plaintext highlighter-rouge">./a.out</code>를 사용해서 <code class="language-plaintext highlighter-rouge">hello.c</code>에 작성하였던 코드의 결과가 출력된다.</p>

<h1 id="6-컴파일-과정">6. 컴파일 과정</h1>
<p><img src="/image/2026-01-01-LinuxC/컴파일과정.png" alt="컴파일과정" /></p>

<h1 id="7-정리">7. 정리</h1>
<p>리눅스 환경에서 <code class="language-plaintext highlighter-rouge">vi 편집기</code>를 이용하여 C 소스 코드를 작성하고, <code class="language-plaintext highlighter-rouge">GCC</code> 컴파일러를 활용해 프로그램을 컴파일 및 실행하는 과정을 수행하였다. 이를 통해 C 프로그램이 소스 코드에서 시작하여 전처리, 컴파일, 어셈블, 링킹 과정을 거쳐 실행 파일로 생성되고 실제로 실행되는 전체 빌드 과정을 이해할 수 있었다.</p>]]></content><author><name>Kang Humin</name></author><category term="C" /><category term="C" /><category term="Linux" /><summary type="html"><![CDATA[1. GCC란 무엇인가 GCC(GNU Compiler Collection)는 C, C++, Java 등 다양한 프로그래밍 언어를 컴파일할 수 있는 컴파일러이다.]]></summary></entry><entry><title type="html">[Data structure] 선형 리스트 원소 삭제</title><link href="https://encryh.github.io/data/structure/ListDelete/" rel="alternate" type="text/html" title="[Data structure] 선형 리스트 원소 삭제" /><published>2025-12-21T00:00:00+09:00</published><updated>2025-12-21T00:00:00+09:00</updated><id>https://encryh.github.io/data/structure/ListDelete</id><content type="html" xml:base="https://encryh.github.io/data/structure/ListDelete/"><![CDATA[<h1 id="선형-리스트-원소-삭제">선형 리스트 원소 삭제</h1>]]></content><author><name>Kang Humin</name></author><category term="Data" /><category term="structure" /><category term="C" /><category term="Data structure" /><summary type="html"><![CDATA[선형 리스트 원소 삭제]]></summary></entry><entry><title type="html">[Data structure] 선형 리스트 원소 삽입</title><link href="https://encryh.github.io/data/structure/ListInsert/" rel="alternate" type="text/html" title="[Data structure] 선형 리스트 원소 삽입" /><published>2025-12-20T00:00:00+09:00</published><updated>2025-12-20T00:00:00+09:00</updated><id>https://encryh.github.io/data/structure/ListInsert</id><content type="html" xml:base="https://encryh.github.io/data/structure/ListInsert/"><![CDATA[<h1 id="선형-리스트-원소-삽입">선형 리스트 원소 삽입</h1>
<p>선형 리스트(Linear List)는 데이터를 순차적으로 저장하는 자료구조이며 일반적으로 배열(Array) 형태로 구현된다.</p>

<p>선형 리스트에서 삽입(Insertion)이란 새로운 데이터를 특정 위치에 추가하는 과정을 의미한다.</p>

<p>배열 기반 선형 리스트에서는 중간 삽입 시 뒤에 있는 원소들을 이동시켜 공간을 만든 후 데이터를 삽입해야 한다.</p>

<h1 id="삽입-알고리즘-전체-흐름">삽입 알고리즘 전체 흐름</h1>
<ol>
  <li>삽입 위치 탐색</li>
  <li>뒤 원소 이동</li>
  <li>데이터 삽입</li>
  <li>리스트 크기 증가</li>
</ol>

<h2 id="1-삽입위치-탐색">1. 삽입위치 탐색</h2>
<p>새로운 원소가 들어갈 삽입 위치 k를 찾는다.</p>

<p>예를 들어 다음과 같은 정렬된 리스트가 있다고 가정한다.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">10</span> <span class="mi">20</span> <span class="mi">40</span> <span class="mi">50</span> <span class="mi">60</span> <span class="mi">70</span>
</code></pre></div></div>
<p>여기에 30을 삽입하려면</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">10</span> <span class="mi">20</span> <span class="mi">30</span> <span class="mi">40</span> <span class="mi">50</span> <span class="mi">60</span> <span class="mi">70</span>
</code></pre></div></div>
<p>이 되어야 하므로 20과 40 사이가 삽입 위치가 된다.</p>

<h2 id="2-뒤-원소-이동">2. 뒤 원소 이동</h2>
<p>배열은 중간에 빈 공간이 없기 때문에 삽입 위치 이후의 원소들을 한 칸씩 뒤로 이동시켜야 한다.</p>

<p>삽입 전</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">10</span> <span class="mi">20</span> <span class="mi">40</span> <span class="mi">50</span> <span class="mi">60</span> <span class="mi">70</span>
      <span class="err">↑</span>
   <span class="mi">30</span> <span class="err">삽입</span> <span class="err">위치</span>
</code></pre></div></div>

<p>원소 이동 과정</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">10</span> <span class="mi">20</span> <span class="n">_</span> <span class="mi">40</span> <span class="mi">50</span> <span class="mi">60</span> <span class="mi">70</span>
</code></pre></div></div>
<p>이 과정에서 뒤에 있는 원소들이 뒤에서부터 한 칸씩 이동하게 된다.</p>

<h2 id="3-새로운-원소-삽입">3. 새로운 원소 삽입</h2>
<p>공간이 확보되면 해당 위치에 새로운 값을 삽입한다.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">10</span> <span class="mi">20</span> <span class="mi">30</span> <span class="mi">40</span> <span class="mi">50</span> <span class="mi">60</span> <span class="mi">70</span>
</code></pre></div></div>

<h2 id="4-리스트-크기-증가">4. 리스트 크기 증가</h2>
<p>삽입이 완료되면 리스트의 원소 개수를 1 증가시킨다.</p>

<h3 id="insertelement">insertElement</h3>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">insertElement</span><span class="p">(</span><span class="kt">int</span> <span class="n">L</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="kt">int</span> <span class="n">x</span><span class="p">){</span>
    <span class="c1">//원소의 크기를 비교하여 삽입 위치 k 찾기</span>
	<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span> <span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">x</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;=</span> <span class="n">L</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span>
		<span class="p">{</span>
			<span class="n">k</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>

    <span class="c1">// 삽입 원소가 가장 큰 경우</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">n</span><span class="p">)</span>
		<span class="n">k</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>

    <span class="c1">// 삽입 원소가 가장 큰 경우</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">n</span><span class="p">)</span>
		<span class="n">k</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>

    <span class="c1">// 삽입 위치에 원소 삽입</span>
    <span class="n">L</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> 
	<span class="k">return</span> <span class="n">move</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h1 id="정리">정리</h1>
<p>배열 기반 선형 리스트는 구조가 단순하고 접근 속도가 빠르다는 장점이 있지만, 삽입이나 삭제 연산 시 기존 데이터를 이동해야 한다는 단점이 존재한다.</p>

<p>이러한 이유로 데이터 삽입과 삭제가 빈번하게 발생하는 경우에는 연결 리스트(Linked List) 와 같은 자료구조를 사용하는 것이 더 효율적일 수 있다.</p>]]></content><author><name>Kang Humin</name></author><category term="Data" /><category term="structure" /><category term="C" /><category term="Data structure" /><summary type="html"><![CDATA[선형 리스트 원소 삽입 선형 리스트(Linear List)는 데이터를 순차적으로 저장하는 자료구조이며 일반적으로 배열(Array) 형태로 구현된다.]]></summary></entry><entry><title type="html">[OverTheWire] Bandit - Level 10 → Level 11</title><link href="https://encryh.github.io/wargame/bandit1011/" rel="alternate" type="text/html" title="[OverTheWire] Bandit - Level 10 → Level 11" /><published>2025-11-30T00:00:00+09:00</published><updated>2025-11-30T00:00:00+09:00</updated><id>https://encryh.github.io/wargame/bandit1011</id><content type="html" xml:base="https://encryh.github.io/wargame/bandit1011/"><![CDATA[<h1 id="level-10--level-11">Level 10 → Level 11</h1>
<p><img src="/image/2025-11-30-bandit1011/bandit1011.png" alt="bandit1011" /></p>

<p>먼저 <code class="language-plaintext highlighter-rouge">data.txt</code> 안에 인코딩된 데이터를 확인하였다.</p>

<p><img src="/image/2025-11-30-bandit1011/인코딩된문자확인.png" alt="인코딩된문자확인" /></p>

<p>쉽게 생각해서 <code class="language-plaintext highlighter-rouge">인코딩</code>된 데이터를 <code class="language-plaintext highlighter-rouge">디코딩</code>하면 비밀번호가 나올거라 생각하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">인코딩</span><span class="p">(</span><span class="n">Encoding</span><span class="p">)</span> <span class="err">⇒</span> <span class="err">데이터를</span> <span class="err">전송하거나</span> <span class="err">저장하기</span> <span class="err">쉽도록</span> <span class="err">특정</span> <span class="err">규칙에</span> <span class="err">따라</span> <span class="err">다른</span> <span class="err">형태로</span> <span class="err">변환하는</span> <span class="err">과정</span>
<span class="p">(</span><span class="err">예</span><span class="o">:</span> <span class="err">바이너리</span> <span class="err">데이터를</span> <span class="n">ASCII</span> <span class="err">문자</span> <span class="err">형태</span><span class="p">(</span><span class="n">Base64</span><span class="p">)</span> <span class="err">로</span> <span class="err">변환</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">디코딩</span><span class="p">(</span><span class="n">Decoding</span><span class="p">)</span> <span class="err">⇒</span> <span class="err">인코딩된</span> <span class="err">데이터를</span> <span class="err">원래의</span> <span class="err">데이터</span> <span class="err">형태로</span> <span class="err">다시</span> <span class="err">변환하는</span> <span class="err">과정</span>
</code></pre></div></div>

<p><img src="/image/2025-11-30-bandit1011/디코딩.png" alt="디코딩" /></p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">base64</span><span class="err">는</span> <span class="err">데이터를</span> <span class="n">Base64</span> <span class="err">형식으로</span> <span class="err">인코딩하거나</span> <span class="err">디코딩하는</span> <span class="err">리눅스</span> <span class="err">명령어이다</span><span class="p">.</span>
<span class="err">주로</span> <span class="err">바이너리</span> <span class="err">데이터를</span> <span class="err">텍스트</span> <span class="err">형태로</span> <span class="err">변환하거나</span> <span class="err">다시</span> <span class="err">원래</span> <span class="err">데이터로</span> <span class="err">복원할</span> <span class="err">때</span> <span class="err">사용된다</span><span class="p">.</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">base64 -d data.txt</code> 명령어를 사용하여 데이터를 디코딩하였고, 그 결과 Level 11로 이동하기 위한 비밀번호를 확인할 수 있었다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">옵션</span><span class="o">-</span><span class="n">d</span> <span class="o">:</span> <span class="n">decode</span> <span class="p">(</span><span class="err">디코딩</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="/image/2025-11-30-bandit1011/접속완료'.png" alt="접속완료'" /></p>

<p>접속완료</p>]]></content><author><name>Kang Humin</name></author><category term="Wargame" /><category term="Linux" /><category term="overthewire" /><category term="bandit" /><summary type="html"><![CDATA[Level 10 → Level 11]]></summary></entry><entry><title type="html">[OverTheWire] Bandit - Level 11 → Level 12</title><link href="https://encryh.github.io/wargame/bandit1112/" rel="alternate" type="text/html" title="[OverTheWire] Bandit - Level 11 → Level 12" /><published>2025-11-30T00:00:00+09:00</published><updated>2025-11-30T00:00:00+09:00</updated><id>https://encryh.github.io/wargame/bandit1112</id><content type="html" xml:base="https://encryh.github.io/wargame/bandit1112/"><![CDATA[<h1 id="level-11--level-12">Level 11 → Level 12</h1>
<p><img src="/image/2025-11-30-bandit1112/bandit1112.png" alt="bandit1112" /></p>

<p>문제 설명을 확인해 보면 data.txt 파일에 저장된 문자열이 소문자(a–z)와 대문자(A–Z)가 각각 13자리씩 회전된 상태라고 되어 있다.</p>

<p>알파벳을 일정한 수만큼 이동시키는 암호 방식에는 여러 종류가 있지만, 13자리씩 회전하는 방식은 ROT13(Rotate by 13 places) 암호 방식이다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">a</span> <span class="err">→</span> <span class="n">n</span> <span class="err">→</span> <span class="n">a</span>
</code></pre></div></div>

<p>또한 ROT13은 같은 변환을 한 번 더 수행하면 원래 문자열로 복원되는 특징이 있다.</p>

<p>따라서 data.txt에 저장된 문자열을 ROT13 방식으로 다시 변환하면 원래 문자열을 확인할 수 있다고 판단하였다.</p>

<p><img src="/image/2025-11-30-bandit1112/data.txt확인.png" alt="data.txt확인" /></p>

<p>먼저 현재 디렉터리에 <code class="language-plaintext highlighter-rouge">data.txt</code> 파일이 존재하는지 확인하였으며, <code class="language-plaintext highlighter-rouge">cat</code> 명령어를 사용해 암호화된 문자열을 확인하였다.</p>

<p>이후 리눅스에는 문자열의 문자를 다른 문자로 변환하는 tr(translate) 명령어가 존재하기 때문에 이를 이용하여 ROT13 방식으로 변환된 문자열을 다시 원래 문자열로 복원할 수 있다고 판단하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tr</span> <span class="err">명령어는</span> <span class="o">**</span><span class="err">문자를</span> <span class="err">다른</span> <span class="err">문자로</span> <span class="err">변환</span><span class="p">(</span><span class="err">치환</span><span class="p">)</span><span class="o">**</span><span class="err">할</span> <span class="err">때</span> <span class="err">사용하는</span> <span class="err">리눅스</span> <span class="err">명령어이다</span><span class="p">.</span>

<span class="n">tr</span> <span class="err">'변환할</span> <span class="err">문자집합</span><span class="sc">' '</span><span class="err">변환될</span> <span class="err">문자집합'</span>
</code></pre></div></div>

<p>1️⃣ ‘A-Za-z’
의미
→ 변환할 문자 범위</p>

<p>구성</p>
<ul>
  <li>A-Z → 대문자 A부터 Z까지</li>
  <li>a-z → 소문자 a부터 z까지
즉 모든 알파벳 문자를 의미한다.</li>
</ul>

<p>2️⃣ ‘N-ZA-Mn-za-m’
의미
→ 변환될 문자 범위 (ROT13)</p>

<p>구성</p>

<p>대문자</p>
<ul>
  <li>A-M → N-Z</li>
  <li>N-Z → A-M</li>
</ul>

<p>소문자</p>
<ul>
  <li>a-m → n-z</li>
  <li>n-z → a-m
즉 알파벳을 13칸 이동시키는 ROT13 변환 규칙이다.</li>
</ul>

<p>3️⃣ 정리</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tr</span> <span class="err">'</span><span class="n">A</span><span class="o">-</span><span class="n">Za</span><span class="o">-</span><span class="n">z</span><span class="sc">' '</span><span class="n">N</span><span class="o">-</span><span class="n">ZA</span><span class="o">-</span><span class="n">Mn</span><span class="o">-</span><span class="n">za</span><span class="o">-</span><span class="n">m</span><span class="err">'</span>
</code></pre></div></div>

<p>‘A-Za-z’는 변환할 모든 알파벳 범위를 의미하고, ‘N-ZA-Mn-za-m’은 ROT13 방식으로 13칸 이동된 문자 범위를 의미한다.</p>

<p><img src="/image/2025-11-30-bandit1112/비밀번호 출력.png" alt="비밀번호 출력" /></p>

<p>위 명령어를 사용해서 Level 12로 이동하기 위한 비밀번호를 확인하였다.</p>

<p><img src="/image/2025-11-30-bandit1112/접속완료.png" alt="접속완료" /></p>

<p>접속완료</p>]]></content><author><name>Kang Humin</name></author><category term="Wargame" /><category term="Linux" /><category term="overthewire" /><category term="bandit" /><summary type="html"><![CDATA[Level 11 → Level 12]]></summary></entry><entry><title type="html">[OverTheWire] Bandit - Level 8 → Level 9</title><link href="https://encryh.github.io/wargame/bandit89/" rel="alternate" type="text/html" title="[OverTheWire] Bandit - Level 8 → Level 9" /><published>2025-11-29T00:00:00+09:00</published><updated>2025-11-29T00:00:00+09:00</updated><id>https://encryh.github.io/wargame/bandit89</id><content type="html" xml:base="https://encryh.github.io/wargame/bandit89/"><![CDATA[<h1 id="level-8--level-9">Level 8 → Level 9</h1>
<p><img src="/image/2025-11-29-bandit89/bandit89.png" alt="bandit89" /></p>

<p>Level 8에서 확인한 결과 <code class="language-plaintext highlighter-rouge">data.txt</code> 파일에는 여러 줄의 텍스트가 존재하며 대부분의 문자열이 중복되어 나타난다.</p>

<p>문제에서 요구하는 것은 한 번만 등장하는 문자열이므로 이를 찾기 위해 <code class="language-plaintext highlighter-rouge">sort</code>와 <code class="language-plaintext highlighter-rouge">uniq</code> 명령어를 함께 사용하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">uniq</span> <span class="err">명령어는</span> <span class="err">중복된</span> <span class="err">줄을</span> <span class="err">제거하거나</span> <span class="err">특정</span> <span class="err">조건의</span> <span class="err">줄을</span> <span class="err">출력하는</span> <span class="err">리눅스</span> <span class="err">명령어이다</span><span class="p">.</span>
</code></pre></div></div>

<p><img src="/image/2025-11-29-bandit89/uniq옵션.png" alt="uniq옵션" /></p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sort</span><span class="err">는</span> <span class="err">텍스트</span> <span class="err">파일의</span> <span class="err">내용을</span> <span class="err">정렬하는</span> <span class="err">리눅스</span> <span class="err">명령어이다</span><span class="p">.</span>
</code></pre></div></div>

<p><img src="/image/2025-11-29-bandit89/비밀번호확인.png" alt="비밀번호확인" /></p>

<p><code class="language-plaintext highlighter-rouge">sort</code> 와 <code class="language-plaintext highlighter-rouge">uniq</code> 명령어를 사용해서 Lever 9로 이동하기 위한 비밀번호를 확인하였다.</p>

<p>| 의 의미 (파이프, Pipe)</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">|</span> <span class="err">는</span> <span class="err">파이프</span><span class="p">(</span><span class="n">Pipe</span><span class="p">)</span> <span class="err">라고</span> <span class="err">하며</span> <span class="err">앞</span> <span class="err">명령어의</span> <span class="err">출력</span> <span class="err">결과를</span> <span class="err">뒤</span> <span class="err">명령어의</span> <span class="err">입력으로</span> <span class="err">전달하는</span> <span class="err">기능을</span> <span class="err">한다</span><span class="p">.</span>
</code></pre></div></div>
<p>실행 순서</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">1</span><span class="err">️⃣</span> <span class="n">sort</span> <span class="n">data</span><span class="p">.</span><span class="n">txt</span>
<span class="err">→</span> <span class="n">data</span><span class="p">.</span><span class="n">txt</span> <span class="err">내용을</span> <span class="err">정렬</span>

<span class="mi">2</span><span class="err">️⃣</span> <span class="o">|</span>
<span class="err">→</span> <span class="err">정렬된</span> <span class="err">결과를</span> <span class="err">다음</span> <span class="err">명령어로</span> <span class="err">전달</span>

<span class="mi">3</span><span class="err">️⃣</span> <span class="n">uniq</span> <span class="o">-</span><span class="n">u</span>
<span class="err">→</span> <span class="err">한</span> <span class="err">번만</span> <span class="err">등장하는</span> <span class="err">줄만</span> <span class="err">출력</span>
</code></pre></div></div>

<p><img src="/image/2025-11-29-bandit89/접속완료'.png" alt="접속완료'" /></p>

<p>접속완료</p>]]></content><author><name>Kang Humin</name></author><category term="Wargame" /><category term="Linux" /><category term="overthewire" /><category term="bandit" /><summary type="html"><![CDATA[Level 8 → Level 9]]></summary></entry><entry><title type="html">[OverTheWire] Bandit - Level 9 → Level 10</title><link href="https://encryh.github.io/wargame/bandit910/" rel="alternate" type="text/html" title="[OverTheWire] Bandit - Level 9 → Level 10" /><published>2025-11-29T00:00:00+09:00</published><updated>2025-11-29T00:00:00+09:00</updated><id>https://encryh.github.io/wargame/bandit910</id><content type="html" xml:base="https://encryh.github.io/wargame/bandit910/"><![CDATA[<h1 id="level-9--level-10">Level 9 → Level 10</h1>
<p><img src="/image/2025-11-29-bandit910/bandit910.png" alt="bandit910" /></p>

<p>먼저 현재 디렉터리에 <code class="language-plaintext highlighter-rouge">data.txt</code> 파일이 존재하는지 확인하였다.</p>

<p>이후 <code class="language-plaintext highlighter-rouge">grep</code> 명령어를 사용하여 <code class="language-plaintext highlighter-rouge">=</code>로 시작하는 문자열을 찾기 위해 다음 명령어를 실행하였다.</p>

<p><img src="/image/2025-11-29-bandit910/=로 시작하는 문자열 찾았는데 바이너리 파일 에러.png" alt="=로 시작하는 문자열 찾았는데 바이너리 파일 에러" /></p>

<p>그러나 명령어 실행 결과 <code class="language-plaintext highlighter-rouge">Binary file matches</code> 오류 메시지가 출력되었다.</p>

<p>이는 <code class="language-plaintext highlighter-rouge">data.txt</code> 파일이 <code class="language-plaintext highlighter-rouge">바이너리(Binary)</code> 데이터가 포함된 파일이기 때문에 일반적인 텍스트 검색이 제대로 수행되지 않았기 때문이다.</p>

<p>따라서 사람이 읽을 수 있는 문자열만 추출하기 위해 <code class="language-plaintext highlighter-rouge">strings</code> 명령어를 사용하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">strings</span> <span class="err">명령어는</span> <span class="err">바이너리</span> <span class="err">파일</span> <span class="err">내부에서</span> <span class="err">사람이</span> <span class="err">읽을</span> <span class="err">수</span> <span class="err">있는</span> <span class="err">문자열을</span> <span class="err">추출하는</span> <span class="err">리눅스</span> <span class="err">명령어이다</span><span class="p">.</span>
</code></pre></div></div>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">strings</span> <span class="n">grep</span> <span class="s">"^="</span> <span class="n">data</span><span class="p">.</span><span class="n">txt</span>
</code></pre></div></div>

<p><img src="/image/2025-11-29-bandit910/strings사용.png" alt="strings사용" /></p>

<p><img src="/image/2025-11-29-bandit910/비밀번호 확인.png" alt="비밀번호 확인" /></p>

<p>위 명령어를 사용해서 Level 10으로 이동하기 위한 비밀번호를 확인할 수 있었다.</p>

<p><img src="/image/2025-11-29-bandit910/접속완료.png" alt="접속완료" /></p>]]></content><author><name>Kang Humin</name></author><category term="Wargame" /><category term="Linux" /><category term="overthewire" /><category term="bandit" /><summary type="html"><![CDATA[Level 9 → Level 10]]></summary></entry><entry><title type="html">[OverTheWire] Bandit - Level 5 → Level 6</title><link href="https://encryh.github.io/wargame/bandit56/" rel="alternate" type="text/html" title="[OverTheWire] Bandit - Level 5 → Level 6" /><published>2025-11-28T00:00:00+09:00</published><updated>2025-11-28T00:00:00+09:00</updated><id>https://encryh.github.io/wargame/bandit56</id><content type="html" xml:base="https://encryh.github.io/wargame/bandit56/"><![CDATA[<h1 id="level-5--level-6">Level 5 → Level 6</h1>

<p><img src="/image/2025-11-28-bandit56/bandit56.png" alt="bandit56" /></p>

<p>먼저 현재 디렉터리에서 파일 목록을 확인한 뒤, inhere 디렉터리가 존재하는 것을 확인하였다.</p>

<p>inhere 디렉터리로 경로를 이동하여 다시 한 번 파일 목록을 확인하였다.</p>

<p><img src="/image/2025-11-28-bandit56/경로이동후파일목록출력.png" alt="경로이동후파일목록출력" /></p>

<p>inhere 디렉터리 내부에는 여러 개의 하위 디렉터리가 존재했기 때문에, 특정 조건을 만족하는 파일을 찾기 위해 <code class="language-plaintext highlighter-rouge">find</code> 명령어를 사용하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">find</span> <span class="err">명령어는</span> <span class="err">파일</span> <span class="err">이름</span><span class="p">,</span> <span class="err">크기</span><span class="p">,</span> <span class="err">권한</span> <span class="err">등</span> <span class="err">다양한</span> <span class="err">조건을</span> <span class="err">기준으로</span> <span class="err">파일을</span> <span class="err">검색하는</span> <span class="err">리눅스</span> <span class="err">명령어이다</span><span class="p">.</span>
</code></pre></div></div>

<p><img src="/image/2025-11-28-bandit56/find명령어사용해서비밀번호확인.png" alt="find명령어사용해서비밀번호확인" /></p>

<p>문제에서 제시된 조건 중 파일 크기가 1033 bytes인 파일을 찾기 위해 다음 명령어를 실행하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">find</span> <span class="o">-</span><span class="n">size</span> <span class="mi">1033</span><span class="n">c</span>
</code></pre></div></div>

<p>명령어 실행 결과 maybehere07/.file2 파일이 조건에 해당하는 파일임을 확인하였다.</p>

<p>이후 cd 명령어를 사용하여 maybehere07 디렉터리로 이동하여 cat 명령어를 사용해서 file2에서 비밀번호를 확인할 수 있었다.</p>

<p><img src="/image/2025-11-28-bandit56/접속완료.png" alt="접속완료" /></p>]]></content><author><name>Kang Humin</name></author><category term="Wargame" /><category term="Linux" /><category term="overthewire" /><category term="bandit" /><summary type="html"><![CDATA[Level 5 → Level 6]]></summary></entry><entry><title type="html">[OverTheWire] Bandit - Level 6 → Level 7</title><link href="https://encryh.github.io/wargame/bandit67/" rel="alternate" type="text/html" title="[OverTheWire] Bandit - Level 6 → Level 7" /><published>2025-11-28T00:00:00+09:00</published><updated>2025-11-28T00:00:00+09:00</updated><id>https://encryh.github.io/wargame/bandit67</id><content type="html" xml:base="https://encryh.github.io/wargame/bandit67/"><![CDATA[<h1 id="level-6--level-7">Level 6 → Level 7</h1>

<p><img src="/image/2025-11-28-bandit67/bandit67.png" alt="bandit67" /></p>

<p>먼저 현재 디렉터리에서 파일 목록을 확인한 뒤, <code class="language-plaintext highlighter-rouge">find</code> 명령어를 사용해서 조건에 맞게 입력해보았다.</p>

<p><img src="/image/2025-11-28-bandit67/파일목록확인후find명령어사용.png" alt="파일목록확인후find명령어사용" /></p>

<p>그러나 명령어 실행 결과 아무런 결과가 출력되지 않았다.</p>

<p>이는 <code class="language-plaintext highlighter-rouge">find</code> 명령어 실행 시 검색할 경로를 지정하지 않았기 때문이다.</p>

<p><code class="language-plaintext highlighter-rouge">find</code> 명령어는 기본적으로 다음과 같은 구조를 가진다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">find</span> <span class="p">[</span><span class="err">검색</span> <span class="err">경로</span><span class="p">]</span> <span class="p">[</span><span class="err">검색</span> <span class="err">조건</span><span class="p">]</span>
</code></pre></div></div>
<p>따라서 검색 경로를 지정하지 않으면 원하는 위치에서 파일을 찾지 못할 수 있다.</p>

<p>문제에서는 파일이 시스템 어딘가에 존재한다고 명시되어 있었기 때문에, <code class="language-plaintext highlighter-rouge">루트 디렉터리(/)</code>부터 전체 시스템을 검색하도록 명령어를 수정하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">find</span> <span class="o">/</span> <span class="o">-</span><span class="n">user</span> <span class="n">bandit7</span> <span class="o">-</span><span class="n">group</span> <span class="n">bandit6</span> <span class="o">-</span><span class="n">size</span> <span class="mi">33</span><span class="n">c</span>
</code></pre></div></div>

<p><img src="/image/2025-11-28-bandit67/경로지정후다시find.png" alt="경로지정후다시find" /></p>

<p>이후 결과가 나오긴 했는데 다음과 같은 오류 메시지가 다수 출력되었다.</p>

<p>이 오류는 현재 사용자 계정(bandit6)이 일부 시스템 디렉터리에 <code class="language-plaintext highlighter-rouge">접근할 권한</code>이 없기 때문에 발생하는 메시지이다.</p>

<p>예를 들어 <code class="language-plaintext highlighter-rouge">/proc, /var/spool</code> 등의 디렉터리는 일반 사용자에게 접근 권한이 제한되어 있어 검색 과정에서 해당 오류가 출력된다.</p>

<p>따라서 검색 결과만 확인하기 위해 표준 오류(stderr)를 숨기는 리다이렉션을 사용하여 명령어를 다시 실행하였다.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">find</span> <span class="o">/</span> <span class="o">-</span><span class="n">user</span> <span class="n">bandit7</span> <span class="o">-</span><span class="n">group</span> <span class="n">bandit6</span> <span class="o">-</span><span class="n">size</span> <span class="mi">33</span><span class="n">c</span> <span class="mi">2</span><span class="o">&gt;/</span><span class="n">dev</span><span class="o">/</span><span class="n">null</span>
</code></pre></div></div>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2</span><span class="o">&gt;/</span><span class="n">dev</span><span class="o">/</span><span class="n">null</span><span class="err">은</span> <span class="err">오류</span> <span class="err">메시지를</span> <span class="err">출력하지</span> <span class="err">않도록</span> <span class="err">버리는</span> <span class="err">리눅스</span> <span class="err">리다이렉션</span> <span class="err">방법</span>
</code></pre></div></div>

<p><img src="/image/2025-11-28-bandit67/비밀번호확인.png" alt="비밀번호확인" /></p>

<p>find 명령어를 사용하여 조건에 해당하는 파일을 검색한 결과 <code class="language-plaintext highlighter-rouge">/var/lib/dpkg/info/bandit7.password </code>경로의 파일을 확인할 수 있었다.</p>

<p>이후 cat 명령어를 사용하여 Level 7로 이동하기 위한 비밀번호를 확인할 수 있었다.</p>

<p><img src="/image/2025-11-28-bandit67/접속완료.png" alt="접속완료" /></p>]]></content><author><name>Kang Humin</name></author><category term="Wargame" /><category term="Linux" /><category term="overthewire" /><category term="bandit" /><summary type="html"><![CDATA[Level 6 → Level 7]]></summary></entry></feed>