사용자 도구

사이트 도구


모르스_부호_변환기

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
모르스_부호_변환기 [2026/09/05 08:12] akpil모르스_부호_변환기 [2026/09/05 09:28] (현재) akpil
줄 5: 줄 5:
 수정된 버전입니다. (2026/09/05) 수정된 버전입니다. (2026/09/05)
  
-수정 사항은 각 문자 사이에 0.3초의 공백이 추가되었습니다.+수정 사항은 각 스페이스 (출력되는 내용에서 '/'로 표시) 사이에 0.3초의 공백이 추가되었습니다.
  
 <code> <code>
-# pip3 install flask jamo+# 2026.09.05  
 +# morse-letter to morse ver 0.7 
 +# written by 6K2LSV 
 +# python3 에서 작동 
 +# pip3 install flask jamo  
 +# port number 3040 
 from flask import Flask, request, render_template_string from flask import Flask, request, render_template_string
 +import json
 from jamo import h2j, j2hcj from jamo import h2j, j2hcj
  
 app = Flask(__name__) app = Flask(__name__)
  
 +# 모르스 부호 사전
 MORSE_DICT = { MORSE_DICT = {
-    'ㄱ': '.-..', 'ㄴ': '..-.', 'ㄷ': '-...', 'ㄹ': '...-', 'ㅁ': '--', 'ㅂ': '.--.', 'ㅅ': '--.', 'ㅇ': '-.-', 'ㅈ': '.---', 'ㅊ': '-.-.', 'ㅋ': '-..-', 'ㅌ': '--..', 'ㅍ': '---.', 'ㅎ': '.---.', +    'ㄱ': '.-..', 'ㄴ': '..-.', 'ㄷ': '-...', 'ㄹ': '...-', 'ㅁ': '--', 'ㅂ': '.--.',  
-    'ㄺ' : '.-....-', 'ㄻ' : '.-..--', 'ㄼ' : '.-.....-', 'ㄿ' : '.-....-.', 'ㅀ' : '.-..--..', 'ㄽ' : '..--...', 'ㄲ': '.-...-..', 'ㄳ' : '--....', 'ntz' : '.---.', 'ㄶ' : '.--...--.', 'ㄸ' : '..--', 'ㅃ' : '..--..', 'ㅆ' : '......', 'ㅄ' : '---.--.-', 'ㅉ' : '..-...-.', +    'ㅅ': '--.', 'ㅇ': '-.-', 'ㅈ': '.---', 'ㅊ': '-.-.', 'ㅋ': '-..-', 'ㅌ': '--..',  
-    'ㅏ' : '.', '야' : '..', 'ㅓ' : '-', 'ㅕ' : '...', 'ㅗ' : '.-', 'ㅛ' : '-.', 'ㅜ' : '....', 'ㅠ' : '.-.', 'ㅡ' : '-..', 'ㅣ' : '..-', 'ㅐ' : '.---', 'ㅔ' : '--..', 'ㅙ' : '.-..-', '' : '..--', '' : '--..', '' : '..--.-','' : '.-.-.-', 'ㅖ' : '..--', 'ㅟ' : '----.-', 'ㅢ' : '...-.-..', +    'ㅍ': '---.', 'ㅎ': '.---.', 'ㄺ' : '.-....-', 'ㄻ' : '.-..--', 'ㄼ' : '.-.....-',  
-    'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', +    'ㄿ' : '.-....-.', 'ㅀ' : '.-..--..', 'ㄽ' : '..--...', 'ㄲ': '.-...-..',  
-    '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----',+    'ㄳ' : '--....', '' : '.---.', 'ㄶ' : '.--...--.', 'ㄸ' : '..--', 'ㅃ' : '..--..',  
 +    'ㅆ' : '......', 'ㅄ' : '---.--.-', 'ㅉ' : '..-...-.', 
 +    'ㅏ' : '.', '야' : '..', 'ㅓ' : '-', 'ㅕ' : '...', 'ㅗ' : '.-', 'ㅛ' : '-.',  
 +    'ㅜ' : '....', 'ㅠ' : '.-.', 'ㅡ' : '-..', 'ㅣ' : '..-', 'ㅐ' : '.---', 'ㅔ' : '--..',  
 +    'ㅙ' : '.-..-', '' : '.-.-.-', '' : '..--', '' : '--..', '' : '..--.-',  
 +    'ㅖ' : '..--', 'ㅟ' : '----.-', 'ㅢ' : '...-.-..', 
 +    'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.',  
 +    'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..',  
 +    'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.',  
 +    'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',  
 +    'Y': '-.--', 'Z': '--..', 
 +    '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....',  
 +    '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----',
     ' ': '/'     ' ': '/'
 } }
줄 27: 줄 47:
 <html> <html>
 <head> <head>
-    <title>한글/영문/숫자 모르스 변환기 (Port 3040)</title>+    <title>모르스 변환기</title>
     <style>     <style>
         body { font-family: 'Segoe UI', sans-serif; text-align: center; background-color: #eef2f3; margin-top: 50px; }         body { font-family: 'Segoe UI', sans-serif; text-align: center; background-color: #eef2f3; margin-top: 50px; }
-        .container { width: 60%; margin: auto; padding: 30px; background: white; border-radius: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.1);+        .container { width: 70%; margin: auto; padding: 30px; background: white; border-radius: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.1);
-        textarea { width: 95%; height: 120px; padding: 15px; font-size: 16px; border: 2px solid #ddd; border-radius: 10px; resize: none; margin-bottom: 15px; } +        textarea { width: 95%; height: 80px; padding: 15px; font-size: 16px; border: 2px solid #ddd; border-radius: 10px; margin-bottom: 15px; } 
-        button { background-color: #4CAF50; color: white; padding: 12px 30px; border: none; border-radius: 8px; font-size: 18px; cursor: pointer; transition: 0.3s; } +        button { background-color: #4CAF50; color: white; padding: 12px 30px; border: none; border-radius: 8px; font-size: 18px; cursor: pointer; } 
-        button:hover background-color: #45a049; } +        .display-area margin-top: 25px; padding: 20px; background: #2d2d2d; border-radius: 10px; min-height: 150px; text-align: left; line-height: 1.8; } 
-        .box text-alignleft; margin-top25px; padding: 15px; border-radius: 8px; border-left: 5px solid #2196F3; background-color: #f9f9f9; } +        .unit display: inline-block; margin-right15px; margin-bottom10px; padding: 5px 10px; border-radius: 5px; background: #444; } 
-        .morse-box background#2d2d2d; color: #ffeb3b; font-family: 'Courier New', monospace; word-break: break-all; font-size: 20pxletter-spacing2px; border-left5px solid #ff9800min-height60px; } +        .char displayblock; color: #fff; font-size: 14pxtext-aligncenter; border-bottom1px solid #666margin-bottom3px; } 
-        h4 margin-bottom5px; color: #555; }+        .morse displayblock; color: #ffeb3b; font-family: monospace; font-size: 18px; text-align: center; }
     </style>     </style>
 </head> </head>
 <body> <body>
     <div class="container">     <div class="container">
-        <h1>📟 사운드 모르스 변환기</h1>+        <h1>📟 한글, 영어, 숫자 모르스 변환기</h1>
         <form method="POST">         <form method="POST">
-            <textarea name="text" placeholder="입력하세요...">{{ input_text }}</textarea><br> +            <textarea name="text" placeholder="내용을 입력하세요...">{{ input_text }}</textarea><br> 
-            <button type="submit">변환 및 재생</button>+            <button type="submit">변환 시작</button>
         </form>         </form>
  
-        {% if result %} +        {% if pair_data %} 
-        <div class="box"> +        <div class="display-area" id="display-area"></div>
-            <h4>📝 입력 데이터 :</h4> +
-            <div style="font-size: 18px;">{{ input_text }}</div> +
-        </div> +
- +
-        <div class="box morse-box"> +
-            <h4>⚡ 모르스 부호 변환 결과 :</h4> +
-            <div id="typing-result"></div> +
-        </div> +
         <script>         <script>
-            const fullText = {{ result | tojson }}; +            const pairData = {{ pair_data | tojson }}; 
-            const displayElement = document.getElementById('typing-result'); +            const displayArea = document.getElementById('display-area');
-            let index = 0; +
- +
-            // Web Audio API 설정+
             const audioCtx = new (window.AudioContext || window.webkitAudioContext)();             const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  
-            function playBeep(isDash) {+            function playBeep(symbol) { 
 +                if (symbol === ' ' || symbol === '/') return 0; // 공백일 때는 비프음 소요 시간 0 반환 
                 const oscillator = audioCtx.createOscillator();                 const oscillator = audioCtx.createOscillator();
                 const gainNode = audioCtx.createGain();                 const gainNode = audioCtx.createGain();
-                +
                 oscillator.connect(gainNode);                 oscillator.connect(gainNode);
                 gainNode.connect(audioCtx.destination);                 gainNode.connect(audioCtx.destination);
-                 
                 oscillator.type = 'sine';                 oscillator.type = 'sine';
-                oscillator.frequency.setValueAtTime(600, audioCtx.currentTime); // 주파수 600Hz +                oscillator.frequency.setValueAtTime(600, audioCtx.currentTime); 
-                 + 
-                const duration = isDash ? 0.2 : 0.07; // 대시(-)는 길게, 도트(.)는 짧게+                const duration = (symbol === '-'? 0.2 : 0.07;
                 gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime);                 gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime);
-                +
                 oscillator.start();                 oscillator.start();
                 oscillator.stop(audioCtx.currentTime + duration);                 oscillator.stop(audioCtx.currentTime + duration);
 +
 +                return duration; // 재생된 시간 반환
             }             }
  
-            function typeAndPlay() { +            async function startDisplay() { 
-                if (index < fullText.length) { +                for (const item of pairData) { 
-                    const char fullText.charAt(index); +                    // 한 글자 단위 박스 생성 
-                    displayElement.innerHTML += char;+                    const unit document.createElement('div'); 
 +                    unit.className = 'unit'; 
 +                    unit.innerHTML = `<span class="char">${item.char === ' ' ? '공백' : item.char}</span><span class="morse" id="m-${item.id}"></span>`; 
 +                    displayArea.appendChild(unit);
  
-                    let nextDelay 100; // 기본 타이핑/재생 간격 (0.1초)+                    const morseSpan document.getElementById(`m-${item.id}`);
  
-                    if (char === '.') { +                    // 해당 문자의 모르스 부호를 한 기호씩 출력 
-                        playBeep(false)+                    for (const symbol of item.morse) { 
-                    } else if (char === '-') { +                        morseSpan.innerText += symbol
-                        playBeep(true); + 
-                    } else if (char === '/') { +                        if (symbol === '/|| symbol === ' ') { 
-                        nextDelay = 300; // 공백 문자(/)를 만나면 0.3초(300ms) 대기+                            // 스페이스 기호가 면 0.3초(300ms) 동안 대기 
 +                            await new Promise(resolve => setTimeout(resolve, 300)); 
 +                        } else { 
 +                            playBeep(symbol); 
 +                            // 일반 기호는 음길이 이후 다음 기호와의 간격을 위해 기존 150ms 대기 
 +                            await new Promise(resolve => setTimeout(resolve, 150)); 
 +                        }
                     }                     }
- 
-                    index++; 
-                    setTimeout(typeAndPlay, nextDelay); // 동적으로 설정된 딜레이 적용 
                 }                 }
             }             }
  
-            window.onload = () => { +            window.onload = startDisplay;
-                if (fullText.length > 0) { +
-                    typeAndPlay(); +
-                } +
-            };+
         </script>         </script>
         {% endif %}         {% endif %}
줄 117: 줄 130:
 @app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
 def index(): def index():
-    result = "" 
     input_text = ""     input_text = ""
 +    pair_data = []
     if request.method == 'POST':     if request.method == 'POST':
         input_text = request.form.get('text', '')         input_text = request.form.get('text', '')
-        processed = j2hcj(h2j(input_text.upper())) +        # 자모 분리 및 대문자화 
-        morse_list = [MORSE_DICT.get(char, char) for char in processed] +        processed_chars list(j2hcj(h2j(input_text.upper()))) 
-        result = " ".join(morse_list+ 
-    return render_template_string(HTML_TEMPLATE, result=result, input_text=input_text)+        for i, char in enumerate(processed_chars): 
 +            pair_data.append({ 
 +                'id': i, 
 +                'char': char, 
 +                'morse': MORSE_DICT.get(char, char) 
 +            }) 
 + 
 +    return render_template_string(HTML_TEMPLATE, pair_data=pair_data, input_text=input_text)
  
 if __name__ == '__main__': if __name__ == '__main__':
     app.run(host='0.0.0.0', port=3040, debug=False)     app.run(host='0.0.0.0', port=3040, debug=False)
 +
 +
 </code> </code>
  
모르스_부호_변환기.1788595942.txt.gz · 마지막으로 수정됨: 저자 akpil

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki