Untitled
#include <iostream> #include <fstream> #include <vector> #include <string> #include <sstream> #include <map> #include <queue> #include <cmath> using namespace std; // Structure to represent a transition in a Finite State Machine (FSM) struct FSMTransition { string inputSignal; // The input signal for the transition string currentState; // The current state before the transition string nextState; // The state the machine transitions to string outputSignal; // The output signal generated by the transition }; // Global variables to store FSM and watermark information extern int numInputSignals; // Number of input signals extern int numOutputSignals; // Number of output signals extern int numStates; // Number of states in FSM extern int numTransitions; // Number of transitions in FSM extern int numPossibleInputs; // Number of possible inputs (2^numInputSignals) extern int watermarkIndex; // Index to track the insertion of watermark inputs extern string initialFSMState; // The initial state of the FSM extern string availableState; // A state available for new transitions extern map<string, map<string, FSMTransition>> fsmTransitionTable; // The FSM transition table extern vector<string> watermarkInputs; // Vector to store watermark input signals extern vector<string> watermarkOutputs; // Vector to store watermark output signals extern vector<string> transitionPath; // Path to track transitions during watermark embedding // Function prototypes static string toStr(int value); // Helper function to convert integer to string inline void createFSMTransition(const string& currentState, const string& inputSignal, const string& outputSignal); // Function to create FSM transitions void parseFSMFile(const string& filename); // Function to parse the FSM input file void parseWatermarkFile(const string& filename); // Function to parse the watermark file void findMissingTransition(const string& state, vector<string> path); // Function to find missing transitions in the FSM string getStartStateOrInsertTransitions(); // Function to get the start state or insert new transitions void embedWatermarkToFSM(); // Function to embed the watermark into the FSM void saveFSMToFile(const string& filename); // Function to save the FSM to a file void saveLatencyToFile(const string& filename); // Function to save the latency path to a file // Initialize global variables int numInputSignals = 0; // Number of input signals in FSM int numOutputSignals = 0; // Number of output signals in FSM int numStates = 0; // Total number of states in FSM int numTransitions = 0; // Total number of transitions in FSM int numPossibleInputs = 0; // 2^numInputSignals possible input combinations int watermarkIndex = 0; // Keeps track of where to insert the watermark in the FSM string initialFSMState; // The FSM's initial state string availableState; // A state available for new transitions // FSM transition table: Maps current state -> input signal -> FSMTransition map<string, map<string, FSMTransition>> fsmTransitionTable; // Vectors for watermark inputs/outputs vector<string> watermarkInputs; vector<string> watermarkOutputs; // Path to track the transition sequence while embedding watermark vector<string> transitionPath; // Main function to execute watermark embedding int main(int argc, char* argv[]) { string fsmInputFile = argv[1]; // Input FSM file string watermarkFile = argv[2]; // Input watermark file string resultFile = argv[3]; // Output FSM file with watermark embedded string latencyFile = argv[4]; // Output latency file // Parse the FSM and watermark files parseFSMFile(fsmInputFile); parseWatermarkFile(watermarkFile); numPossibleInputs = 1 << numInputSignals; // Calculate the number of possible inputs // Embed the watermark into the FSM embedWatermarkToFSM(); // Save the modified FSM and latency information saveFSMToFile(resultFile); saveLatencyToFile(latencyFile); cout << "Watermark embedding completed successfully!" << endl; return 0; } // Function to convert an integer to string static string toStr(int value) { ostringstream oss; oss << value; return oss.str(); } // Function to create a new FSM transition with a specified current state, input, and output signals inline void createFSMTransition(const string& currentState, const string& inputSignal, const string& outputSignal) { FSMTransition transition; transition.inputSignal = inputSignal; transition.currentState = currentState; transition.nextState = "S" + toStr(numStates++); // Increment and assign a new state name transition.outputSignal = outputSignal; fsmTransitionTable[currentState][inputSignal] = transition; // Insert transition into the FSM table } // Function to parse the FSM file and populate global FSM variables void parseFSMFile(const string& filename) { ifstream file(filename.c_str(), ios::in); // Open the FSM file for reading if (!file.is_open()) { cerr << "Error opening FSM file." << endl; return; } string line; while (getline(file, line)) { if (line.empty() || line[0] == '#') // Skip empty lines or comments { continue; } if (line[0] == '.') // Parse FSM configuration settings { istringstream iss(line); if (line[1] == 'i') // Number of input signals { iss >> line >> numInputSignals; } else if (line[1] == 'o') // Number of output signals { iss >> line >> numOutputSignals; } else if (line[1] == 'p') // Number of transitions { iss >> line >> numTransitions; } else if (line[1] == 's') // Number of states { iss >> line >> numStates; } else if (line[1] == 'r') // Initial state { iss >> line >> initialFSMState; } else if (line[1] == 'e') // End marker { break; } } else // Parse FSM transitions { FSMTransition transition; istringstream iss(line); iss >> transition.inputSignal >> transition.currentState >> transition.nextState >> transition.outputSignal; fsmTransitionTable[transition.currentState][transition.inputSignal] = transition; // Add transition to FSM table } } file.close(); } // Function to parse the watermark file and extract input/output signal segments void parseWatermarkFile(const string& filename) { ifstream file(filename.c_str(), ios::in); // Open the watermark file for reading if (!file.is_open()) { cerr << "Error opening watermark file." << endl; return; } string watermark; getline(file, watermark); // Read the entire watermark into a string file.close(); int segmentLength = numInputSignals + numOutputSignals; size_t idx = 0; while (idx + segmentLength <= watermark.size()) { // Split the watermark into input/output signal segments string inputSegment = watermark.substr(idx, numInputSignals); string outputSegment = watermark.substr(idx + numInputSignals, numOutputSignals); watermarkInputs.push_back(inputSegment); // Store input signal watermarkOutputs.push_back(outputSegment); // Store output signal idx += segmentLength; } } // Function to recursively find missing transitions and mark the state path void findMissingTransition(const string& state, vector<string> path) { if (fsmTransitionTable[state].size() < (size_t)numPossibleInputs) { // Check if there are missing transitions for the current state for (int i = 0; i < numPossibleInputs; i++) { string binaryInput; int temp = i; while (temp > 0) { binaryInput = ((temp % 2) ? "1" : "0") + binaryInput; temp /= 2; } while (binaryInput.size() < (size_t)numInputSignals) { binaryInput = "0" + binaryInput; // Pad binary input to match input signal count } if (fsmTransitionTable[state].find(binaryInput) == fsmTransitionTable[state].end()) { // Record the transition path and available state if transition is missing transitionPath = path; transitionPath.push_back(binaryInput); availableState = state; return; } } } else { // Recursively search through the FSM transitions for missing transitions for (const auto& pair : fsmTransitionTable[state]) { path.push_back(pair.first); findMissingTransition(pair.second.nextState, path); path.pop_back(); } } } // Function to get the start state for watermark embedding, or insert new transitions if necessary string getStartStateOrInsertTransitions() { if (fsmTransitionTable[initialFSMState][watermarkInputs[0]].outputSignal == watermarkOutputs[0]) { return initialFSMState; // If the initial state already matches, return it as the start state } else { string startState = ""; for (; startState == ""; watermarkIndex++) { // Search through FSM transitions to find matching transitions for (const auto& statePair : fsmTransitionTable) { if (statePair.second.find(watermarkInputs[watermarkIndex]) != statePair.second.end()) { const FSMTransition& transition = statePair.second.at(watermarkInputs[watermarkIndex]); if (transition.outputSignal == watermarkOutputs[watermarkIndex]) { startState = statePair.first; // Found matching state break; } } } } watermarkIndex--; // Decrease index after finding the start state // Find missing transition if any findMissingTransition(initialFSMState, vector<string>()); // Create the missing transition createFSMTransition(availableState, transitionPath.back(), watermarkOutputs[0]); string newlyCreatedState = "S" + toStr(numStates - 1); // Create the remaining watermark transitions for (int i = 0; i < watermarkIndex; i++) { createFSMTransition(newlyCreatedState, watermarkInputs[i], watermarkOutputs[i]); } // If it's the first watermark input, create a transition back to the start state if (watermarkIndex == 0) { FSMTransition transition; transition.inputSignal = watermarkInputs[watermarkIndex]; transition.currentState = newlyCreatedState; transition.nextState = startState; transition.outputSignal = watermarkOutputs[watermarkIndex]; fsmTransitionTable[newlyCreatedState][watermarkInputs[watermarkIndex]] = transition; transitionPath.push_back(watermarkInputs[watermarkIndex]); } else { // Create transition back to the start state for other watermark inputs FSMTransition transition; transition.inputSignal = watermarkInputs[watermarkIndex - 1]; transition.currentState = newlyCreatedState; transition.nextState = startState; transition.outputSignal = watermarkOutputs[watermarkIndex - 1]; fsmTransitionTable[newlyCreatedState][watermarkInputs[watermarkIndex - 1]] = transition; startState = newlyCreatedState; } return startState; // Return the start state after embedding watermark transitions } } // Function to embed watermark signals into the FSM void embedWatermarkToFSM() { string currentState = getStartStateOrInsertTransitions(); // Get or insert start state for watermark // For each watermark output, embed it into the FSM transitions for (size_t i = 0; i < watermarkOutputs.size(); i++) { if (static_cast<int>(i) < watermarkIndex) { // Check if the current state already has the transition if (fsmTransitionTable[currentState].find(watermarkInputs[i]) == fsmTransitionTable[currentState].end()) { // Create a new transition if it does not exist createFSMTransition(currentState, watermarkInputs[i], watermarkOutputs[i]); currentState = fsmTransitionTable[currentState][watermarkInputs[i]].nextState; numTransitions++; // Increment transition count } else if (fsmTransitionTable[currentState][watermarkInputs[i]].outputSignal == watermarkOutputs[i]) { // If the transition already exists and the output signal matches, move to next state currentState = fsmTransitionTable[currentState][watermarkInputs[i]].nextState; } else { // If the transition output doesn't match, create a new transition string lastCreatedState = "S" + toStr(numStates - 1); createFSMTransition(lastCreatedState, watermarkInputs[i], watermarkOutputs[i]); currentState = lastCreatedState; numTransitions++; // Increment transition count } } else { // For remaining watermark outputs, always create a new transition string lastCreatedState = "S" + toStr(numStates - 1); createFSMTransition(lastCreatedState, watermarkInputs[i], watermarkOutputs[i]); currentState = lastCreatedState; numTransitions++; // Increment transition count } } } // Function to save the FSM to an output file void saveFSMToFile(const string& filename) { ofstream file(filename.c_str(), ios::out); // Open the output file for writing if (!file.is_open()) { cerr << "Error." << endl; return; } // Write FSM configuration settings file << ".i " << numInputSignals << "\n"; file << ".o " << numOutputSignals << "\n"; file << ".p " << numTransitions << "\n"; file << ".s " << numStates << "\n"; file << ".r " << initialFSMState << "\n"; // Write FSM transitions for (const auto& statePair : fsmTransitionTable) { for (const auto& transitionPair : statePair.second) { const FSMTransition& transition = transitionPair.second; file << transition.inputSignal << " " << transition.currentState << " " << transition.nextState << " " << transition.outputSignal << "\n"; } } file << ".e\n"; // End marker file.close(); } // Function to save the latency path to a file void saveLatencyToFile(const string& filename) { ofstream file(filename.c_str(), ios::out); // Open the latency file for writing if (!file.is_open()) { cerr << "Error." << endl; return; } file << ".n " << transitionPath.size() << "\n"; // Write the size of the transition path for (size_t i = 0; i < transitionPath.size(); i++) { if (i > 0) file << "_"; // Separator between transition path elements file << transitionPath[i]; } file << "\n.e\n"; // End marker file.close(); }
Leave a Comment