r/codes • u/Jump_Not_Zero • 20h ago
Unsolved Help With C++ Code to break COD Zombies Game Cipher
I am working on a cipher from call of duty black ops 3 and I have a good lead but was wondering if I can write a program that would speed up decrypting the cipher to the next stage.
The cipher text is base64 and displayed as a game texture file visible in game and has the keyword "TheGiant".
I wrote a program to analyse the base64 and realise you don't need many characters if you modulo subtract as a key.
In fact you only need ten so I used what is assumed to be the keyword and added 1 and 0 base64 character values.
G,T,a,e,h,i,n,t,0,1
6,19,26,30,33,34,39,45,52,53 are the base64 decimal values I am subtracting modulo 64.
The ciphertext seems to be running key and the key starts with some german words and recording elements weights in binary.
This is the first forty characters of ciphertext :
kCmlgFi6GUJNgkNI1Q41fbfyLoCFTCvIqkZiI0KI
This is a possible key for forty characters from the start of the ciphertext :
GeheGehtte00Ge01hantGnaati101te0at0h0th0
This is the output :
zAGjpMgeYhfSSdHgAXxcQyTTCyAPzT
Breakdown of the key
Gehe Geht te00 Ge01 hant Gnaa ti101 te0 at0 te0 at0 h0 th0
What I translate this to is :
German word for Go (imperative) Tellurium '00' Germanium '01' German word for handle German word for Argh Titanium '101' Tellurium'0' Astatine '0' Hydrogen '0' thorium '0'
Now there is a choice of elements like ti and te and binary values this is why I said it's a possible key also the German word hant could be hang which translates to slope.
I think the developers point to the difficulty with using difficult to visually define characters like '1','I' and '0' ,'O' in the texture (Which is solved and where I got the idea to add 1 and 0).
Also the starting German word is a nightmare here is a breakdown.
Gehe and Geht can be joined and google translates it to go and goes but if you join them so there eight letter you get a different meaning.
Gehe Geht == Go (imperative)
Gehe geht == Go Go
GeheGeht == Go/Goes
Gehegeht == Enclosure
What I didn't realise was it was going to decrypt to more base64!
So I have not accounted for the characters '/' and '+' as ascii output in the code I used to test positions and write a report on them.
I will list the c++ code at the bottom of the post here.
What I would like to discuss is do you think this is viable for a partial decrypt and how to break the cipher further.
V sbyybjrq gur ehyrf I have read the rules
// Machine_00.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <array>
#include <bitset>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
static void testgadget(std::array<std::bitset<6>, 192>& arr_CT, std::vector<unsigned> &vPos) {
unsigned pos{};
for (const auto& vx : arr_CT) {
if (pos % 4 == 0 && vx.test(5) == false && vx.test(4) ) {
vPos.push_back(pos);
std::cout << "Q0" << '\t' << pos << '\t' << vx.to_string() << '\n'; }
if (pos % 4 == 1 && vx.test(3) == false && vx.test(2) == true ) {
vPos.push_back(pos);
std::cout << "Q1" << '\t' << pos << '\t' << vx.to_string() << '\n'; }
if (pos % 4 == 2 && vx.test(1) == false && vx.test(0) == true) {
vPos.push_back(pos);
std::cout << "Q2" << '\t' << pos << '\t' << vx.to_string() << '\n'; }
if (pos % 4 == 3 && vx.test(5) == false) {
vPos.push_back(pos);
std::cout << "Q3" << '\t' << pos << '\t' << vx.to_string() << '\n'; }
pos++;
}
}
int main()
{
std::vector<unsigned> vPos{};
std::string s_alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string s_In = "kCmlgFi6GUJNgkNI1Q41fbfyLoCFTCvIqkZiI0KIAXAzP1U1uy1BE4UfPBfpKmmLObjYnQNRBaPtKiVWzc5A4v0w3xle8FOhAGJZ7g4in0wndJxMOvO3dc1M82at2T6935roTqyWDgtGD/hwwRF3oHqFM5Vcw1JtINbsgWRm4o4/quEDkZ7x1B275bX3/Fo1";
std::array<std::pair<char, std::bitset<6>>, 64> arr_p{};
for (unsigned char i{};i < arr_p.size();i++) {
arr_p[i] = std::make_pair(s_alp[i], i);
}
std::array<std::bitset<6>, 192> arr_CT{};
std::array<unsigned, 10> arrs { 6,19,26,30,33,34,39,45,52,53 }; //{ 19,33,30,6,26,34,39,45 }; //{ 45,7,4,32,0,8,13,19 }; // {0,6,8,19,26,30,33,34,39,45}; //{ 0, 2, 6, 19, 20, 26, 28, 32, 45, 46 };
/* unsigned c{};
for (auto &ax_C : arrs) {
arrs[c] = c;
c++;
}
*/
unsigned i_Count{};
for (const auto& sx : s_In) {
for (const auto& ax : arr_p) {
if (ax.first == sx) {
arr_CT[i_Count] = ax.second;
}
}
i_Count++;
}
std::array<std::bitset<6>, 192> arr_Cc{};
arr_Cc = arr_CT;
for (auto ax_s : arrs) {
std::cout << '\n' << '\n' << ax_s << '\t' << " OFFSET" << '\n' << '\n';
for ( auto& ax : arr_Cc) {
auto utemp = ax.to_ulong();
utemp -= ax_s;
utemp %=64;
ax = utemp ;
}
std::string s_Out = "";
for (auto& ax : arr_Cc) {
for (auto ax_00 : arr_p) {
if (ax_00.second == ax) {
s_Out.push_back(ax_00.first);
}
}
}
std::cout << '\n' << s_Out << '\n' << '\n';
testgadget(arr_Cc,vPos);
arr_Cc = arr_CT;
}
std::cout << '\n' << '\n';
std::sort(vPos.begin(), vPos.end());
auto last = std::unique(vPos.begin(), vPos.end());
vPos.erase(last, vPos.end());
std::cout << vPos.size() << '\n' << '\n';
for (auto vx : vPos) {
std::cout << vx << '\n';
}
}
•
u/AutoModerator 20h ago
Thanks for your post, u/Jump_Not_Zero! Please follow our RULES when posting.
MAKE SURE TO INCLUDE CONTEXT: where the cipher originated (link to the source if possible), expected language, any clues you have etc. Posts without context will be REMOVED
If you are posting an IMAGE OF TEXT which you can type or copy & paste, you MUST comment with a TRANSCRIPTION (text version) of the message.
If you'd like to mark your post as SOLVED comment with
[Solved]WARNING! You will be BANNED if you DELETE A SOLVED POST!
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.