コードをメモ帳などのテキストエディタに貼り付け、ファイル名を「index.html」として保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。
ジャミング周波数を回避してモールス通信を行うゲームです。
モールス信号の発信時に周波数を変更したり、ホワイトノイズを利用してジャミングを行えます。
周波数スライダー: 周波数を調整できるスライダーを追加し、600Hzを初期値にしました。
ジャミングボタン: 「ジャミング開始」と「ジャミング停止」ボタンを追加し、現在の周波数でホワイトノイズを生成する機能を実装しました。
このコードを使えば、周波数を調整しながらモールス信号を発信し、ホワイトノイズでジャミングすることができます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MORS発信</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin-top: 50px;
}
input {
padding: 10px;
width: 300px;
font-size: 18px;
}
button {
padding: 10px 20px;
font-size: 18px;
margin-top: 10px;
}
/* 現在送信中の文字を大きく表示するスタイル */
#currentChar {
font-size: 100px;
color: #333;
margin: 20px;
height: 120px;
}
/* 現在送信中のモールス符号を表示するスタイル */
#currentMorse {
font-size: 30px;
color: #666;
}
#speedLabel, #freqLabel {
margin-top: 20px;
font-size: 18px;
}
#speedSlider, #freqSlider {
width: 300px;
}
</style>
</head>
<body>
<h1>MORS信号発信機</h1>
<p>メッセージを入力してください:</p>
<input type="text" id="messageInput" value="Hello World 12345">
<br><br>
<button onclick="sendMorse()">MORS発信</button>
<br><br>
<!-- スピード調整用のスライダー -->
<p id="speedLabel">速度調整: 1x</p>
<input type="range" id="speedSlider" min="0.5" max="2" step="0.1" value="1" oninput="updateSpeed()">
<br><br>
<!-- 周波数調整用のスライダー -->
<p id="freqLabel">周波数: 600Hz</p>
<input type="range" id="freqSlider" min="300" max="1000" step="10" value="600" oninput="updateFrequency()">
<br><br>
<!-- ホワイトノイズ用のジャミングボタン -->
<button onclick="startJamming()">ジャミング開始</button>
<button onclick="stopJamming()">ジャミング停止</button>
<br><br>
<div id="currentChar"></div>
<div id="currentMorse"></div>
<audio id="morseSound"></audio>
<script>
const morseCode = {
'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': '-----', ' ': ' '
};
let dotDuration = 100;
let dashDuration = 300;
let betweenSymbols = 100;
let betweenLetters = 300;
let speedFactor = 1;
let frequency = 600; // 初期周波数
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
let oscillator;
let jammingOscillator;
// スピード調整
function updateSpeed() {
const slider = document.getElementById('speedSlider');
speedFactor = slider.value;
document.getElementById('speedLabel').innerText = `速度調整: ${speedFactor}x`;
dotDuration = 100 / speedFactor;
dashDuration = 300 / speedFactor;
betweenSymbols = 100 / speedFactor;
betweenLetters = 300 / speedFactor;
}
// 周波数調整
function updateFrequency() {
const slider = document.getElementById('freqSlider');
frequency = slider.value;
document.getElementById('freqLabel').innerText = `周波数: ${frequency}Hz`;
}
function playMorseSound(duration) {
oscillator = audioContext.createOscillator();
oscillator.type = 'sine';
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime); // スライダーで指定された周波数
oscillator.connect(audioContext.destination);
oscillator.start();
setTimeout(() => oscillator.stop(), duration);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function sendMorse() {
const message = document.getElementById('messageInput').value.toLowerCase();
const morseMessage = message.split('').map(char => morseCode[char] || '').join(' ');
for (let char of message) {
const morse = morseCode[char] || '';
document.getElementById('currentChar').innerText = char.toUpperCase();
document.getElementById('currentMorse').innerText = morse;
for (let symbol of morse) {
if (symbol === '.') {
playMorseSound(dotDuration);
await sleep(dotDuration + betweenSymbols);
} else if (symbol === '-') {
playMorseSound(dashDuration);
await sleep(dashDuration + betweenSymbols);
}
}
await sleep(betweenLetters);
}
sendMorse();
}
// ジャミング用のホワイトノイズを生成する関数
function startJamming() {
jammingOscillator = audioContext.createOscillator();
jammingOscillator.type = 'white'; // ノイズ
jammingOscillator.frequency.setValueAtTime(frequency, audioContext.currentTime); // 現在の周波数でジャミング
jammingOscillator.connect(audioContext.destination);
jammingOscillator.start();
}
function stopJamming() {
if (jammingOscillator) {
jammingOscillator.stop();
jammingOscillator.disconnect();
}
}
</script>
</body>
</html>
モールス信号のように音を使った通信では、信号が占有する周波数帯域を覆うホワイトノイズを生成することで、その信号を妨害(ジャミング)できます。ただし、ホワイトノイズの強度が信号よりも十分に大きい必要があります。強力なホワイトノイズを生成すれば、特定の周波数の信号がホワイトノイズに埋もれてしまい、信号が聞き取れなくなるか、正確に解読できなくなります。
ホワイトノイズは全ての周波数帯域に均等にエネルギーを分配するため、もし広範囲の周波数帯域をカバーしようとする場合、各周波数に十分な強度を持たせるためには膨大な総エネルギーが必要になります。
つまり困難であるということです。