// Copyright (C) 2007-2025 EQ2EMulator // Licensed under GPL v3 #include "rc4.h" #include #include #include static constexpr std::array get_init_state() noexcept { std::array state{}; std::iota(state.begin(), state.end(), 0); return state; } static const auto g_init_state = get_init_state(); RC4::RC4(int64 key) noexcept { Init(key); } void RC4::Init(int64 key) noexcept { m_state = g_init_state; m_x = 0; m_y = 0; ulong key_index = 0; ulong state_index = 0; const auto* key_ptr = reinterpret_cast(&key); for (int16 i = 0; i < 256; ++i) { const ulong temp = m_state[i]; state_index += key_ptr[key_index] + temp; state_index &= 0xFF; m_state[i] = m_state[state_index]; m_state[state_index] = static_cast(temp); key_index++; key_index &= 7; } } void RC4::Cypher(uchar* data, int32 length) noexcept { uchar key1 = m_x; uchar key2 = m_y; for (int32 i = 0; i < length; ++i) { ++key1; const uchar key_val1 = m_state[key1]; key2 += key_val1; const uchar key_val2 = m_state[key2]; m_state[key1] = key_val2; m_state[key2] = key_val1; data[i] ^= m_state[(key_val1 + key_val2) & 0xFF]; } m_x = key1; m_y = key2; }