Loading include/Device.h 0 → 100644 +101 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_MACHINE_H #define HW5_ADMIN_MACHINE_H #include <complex> #include <utility> #include "Password.h" /** * Represents one machine on the network. */ class Device { public: // CONSTRUCTORS explicit Device(Password pwd) : loginPassword(std::move(pwd)) { myID = globalDeviceID++; } /** * Devices cannot be constructed without a password. */ Device() = delete; /** * Devices cannot be copied. */ Device(const Device &other) = delete; // MODIFIERS /** * Change the device's password to \ref newPwd. * @param newPwd The new password for the device. */ void changePassword(const Password &newPwd) { loginPassword = newPwd; } /** * Changes the current Device's password to match that of \ref dev. * @param dev The Device whose password should be copied to this object. */ void changePassword(const Device &dev) { loginPassword = dev.loginPassword; } // COMPARISONS /** * Compares Devices by their unique ID. * @return true iff this Device equals \ref otherDev */ bool operator==(const Device &otherDev) const { return myID == otherDev.myID; } /** * Relatively compares Devices by some fixed, but arbitrary, measure. * @return iff this Device is less than \ref otherDev by some fixed by arbitrary measure. */ bool operator<(const Device &other) const { return myID < other.myID; } /** * @return true iff Device \ref devA and Device \ref devB have the same password. */ static bool samePassword(const Device &devA, const Device &devB) { return devA.loginPassword == devB.loginPassword; } // INFORMATIONAL /** * @return A human-readable version of this Device. */ [[nodiscard]] string toString() const { stringstream strS; strS << "(device #" << myID << ": " << loginPassword << ")"; return strS.str(); } /** * Stream access to Device */ friend std::ostream &operator<<(std::ostream &os, const Device &dev) { os << dev.toString(); return os; } friend class Password; private: /** * An ID for this Device that is different from the ID of any other Device. */ int myID; /** * A login password for this Device. */ Password loginPassword; /** * A unique (among devices) global device ID counter. */ static int globalDeviceID; }; #endif // HW5_ADMIN_MACHINE_H include/Password.h 0 → 100644 +79 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_PASSWORD_H #define HW5_ADMIN_PASSWORD_H #include <random> #include <sstream> #include <string> using namespace std; /** * Represents a password that can be used for logging into a Device. */ class Password { public: /** * Construct a new Password object. */ Password() { passID = globalPassID++; myPass = generatePassword(); } /** * Compares two Passwords by their unique IDs. * @return true iff this Password and \ref otherPwd have the same ID. */ bool operator==(const Password& otherPwd) const { return passID == otherPwd.passID; } /** * Stream access to Password */ friend std::ostream& operator<<(std::ostream& os, const Password& pwd) { os << pwd.toString(); return os; } private: /** * Generates a random password. * @return A random password. */ static string generatePassword() { constexpr int PASS_LEN = 5; // default length of a password static random_device rd; // seed (slow, once per program) static mt19937 gen(rd()); // fast, deterministic after seeding static uniform_int_distribution dist(65, 90); // letters A - Z, inclusive string str; for (size_t i = 0; i < PASS_LEN; ++i) { str.push_back(static_cast<char>(dist(gen))); } return str; } /** * An ID for this Password that is different from the ID of any other Password. */ int passID; /** * A plaintext password. */ string myPass; /** * Global counter to ensure that each Password has a unique ID. */ static int globalPassID; }; #endif // HW5_ADMIN_PASSWORD_H include/Service.h 0 → 100644 +106 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_SERVICE_H #define HW5_ADMIN_SERVICE_H #include <sstream> #include <string> #include <unordered_set> #include "../include/Device.h" using namespace std; /** * Represents a Service utilizing two or more devices */ class Service { public: // CONSTRUCTORS /** * Creates a Service utilizing between two or more Devices. * @requires d1 != d2 */ template<typename... Rest> Service(Device &d1, Device &d2, Rest &...rest) { serviceID = globalServiceID++; addDevice(d1); addDevice(d2); (addDevice(rest), ...); } /** * A Service cannot be created through the default constructor. */ Service() = delete; /** * Services cannot be copied. */ Service(const Service &otherSvc) = delete; // MODIFIERS /** * Add a Device to this Service. * @param dev The Device to add. */ void addDevice(Device &dev); // INFORMATIONAL /** * @return A collection of all Device s associated with this Service. */ [[nodiscard]] const unordered_set<Device *> &getDevices() const; /** * @param dev The Device to check in this Service. * @return true iff this Service involves the given Device */ bool hasDevice(Device &dev) const; /** * Compares Service objects by their unique ID. * @return true if this Service equals \ref otherSvc */ bool operator==(const Service &otherSvc) const { return serviceID == otherSvc.serviceID; } /** * @return A human-readable version of this Service. */ [[nodiscard]] string toString() const { stringstream strS; strS << "[ service #" << serviceID << " ] "; for (const auto dev : devices) { strS << *dev << " "; } return strS.str(); } /** * Stream access to Service. */ friend std::ostream &operator<<(std::ostream &os, const Service &svc) { os << svc.toString(); return os; } private: /** * A collection of Devices associated with this Service */ unordered_set<Device *> devices; /** * The ID of this Service. */ int serviceID; static int globalServiceID; }; #endif // HW5_ADMIN_SERVICE_H include/System.h 0 → 100644 +84 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_SYSTEM_H #define HW5_ADMIN_SYSTEM_H #include <unordered_set> #include "Service.h" /** * Represents a system of devices and their servicess. */ class System { public: // MODIFIERS /** * Creates a system with an arbitrary number of Devices. * Each Device is provided by reference. */ template<typename... Rest> explicit System(const Rest &...rest) { (addService(rest), ...); } /** * Adds a new Service to the System * @param newSvc The new Service to add. */ void addService(const Service &newSvc); // GETTERS /** * @return All unique Device s associated with this System. */ [[nodiscard]] unordered_set<Device *> getAllDevices() const; /** * @return All unique Service s associated with this System. */ [[nodiscard]] unordered_set<const Service *> getServices() const; // INFORMATIONAL /** * * @return true iff the System is considered secure, meaning that * any two Devices on the same Service have different Passwords. */ [[nodiscard]] bool isSecureQ() const; /** * @return A human-readable version of this System. */ [[nodiscard]] string toString() const { stringstream strS; for (const auto svc : services) { strS << '\t' << *svc << endl; } strS << '\t' << "Is it secure? " << (isSecureQ()?"yes":"no") << endl; strS << '\t' << "# of unique passwords: " << numPasswords() << endl; return strS.str(); } /** * @return The number of unique Passwords associated with the System. */ [[nodiscard]] long numPasswords() const; /** * Stream access to System. */ friend std::ostream &operator<<(std::ostream &os, const System &sys) { os << sys.toString(); return os; } private: /** * Services stored by the system. */ unordered_set<const Service *> services; }; #endif // HW5_ADMIN_SYSTEM_H main.cpp 0 → 100644 +23 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #include <iostream> #include "include/Service.h" #include "include/Device.h" #include "include/Password.h" #include "include/System.h" int main() { Password p1, p2, p3; Device dev0(p1), dev1(p2), dev2(p3); Service svc0(dev0, dev1); Service svc1(dev0, dev1, dev2); Service svc2(dev0, dev2); System sys(svc0, svc1, svc2); cout << "Initial system:" << endl << sys << endl; dev1.changePassword(p1); cout << "Changed password of dev1:" << endl << sys << endl; } Loading
include/Device.h 0 → 100644 +101 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_MACHINE_H #define HW5_ADMIN_MACHINE_H #include <complex> #include <utility> #include "Password.h" /** * Represents one machine on the network. */ class Device { public: // CONSTRUCTORS explicit Device(Password pwd) : loginPassword(std::move(pwd)) { myID = globalDeviceID++; } /** * Devices cannot be constructed without a password. */ Device() = delete; /** * Devices cannot be copied. */ Device(const Device &other) = delete; // MODIFIERS /** * Change the device's password to \ref newPwd. * @param newPwd The new password for the device. */ void changePassword(const Password &newPwd) { loginPassword = newPwd; } /** * Changes the current Device's password to match that of \ref dev. * @param dev The Device whose password should be copied to this object. */ void changePassword(const Device &dev) { loginPassword = dev.loginPassword; } // COMPARISONS /** * Compares Devices by their unique ID. * @return true iff this Device equals \ref otherDev */ bool operator==(const Device &otherDev) const { return myID == otherDev.myID; } /** * Relatively compares Devices by some fixed, but arbitrary, measure. * @return iff this Device is less than \ref otherDev by some fixed by arbitrary measure. */ bool operator<(const Device &other) const { return myID < other.myID; } /** * @return true iff Device \ref devA and Device \ref devB have the same password. */ static bool samePassword(const Device &devA, const Device &devB) { return devA.loginPassword == devB.loginPassword; } // INFORMATIONAL /** * @return A human-readable version of this Device. */ [[nodiscard]] string toString() const { stringstream strS; strS << "(device #" << myID << ": " << loginPassword << ")"; return strS.str(); } /** * Stream access to Device */ friend std::ostream &operator<<(std::ostream &os, const Device &dev) { os << dev.toString(); return os; } friend class Password; private: /** * An ID for this Device that is different from the ID of any other Device. */ int myID; /** * A login password for this Device. */ Password loginPassword; /** * A unique (among devices) global device ID counter. */ static int globalDeviceID; }; #endif // HW5_ADMIN_MACHINE_H
include/Password.h 0 → 100644 +79 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_PASSWORD_H #define HW5_ADMIN_PASSWORD_H #include <random> #include <sstream> #include <string> using namespace std; /** * Represents a password that can be used for logging into a Device. */ class Password { public: /** * Construct a new Password object. */ Password() { passID = globalPassID++; myPass = generatePassword(); } /** * Compares two Passwords by their unique IDs. * @return true iff this Password and \ref otherPwd have the same ID. */ bool operator==(const Password& otherPwd) const { return passID == otherPwd.passID; } /** * Stream access to Password */ friend std::ostream& operator<<(std::ostream& os, const Password& pwd) { os << pwd.toString(); return os; } private: /** * Generates a random password. * @return A random password. */ static string generatePassword() { constexpr int PASS_LEN = 5; // default length of a password static random_device rd; // seed (slow, once per program) static mt19937 gen(rd()); // fast, deterministic after seeding static uniform_int_distribution dist(65, 90); // letters A - Z, inclusive string str; for (size_t i = 0; i < PASS_LEN; ++i) { str.push_back(static_cast<char>(dist(gen))); } return str; } /** * An ID for this Password that is different from the ID of any other Password. */ int passID; /** * A plaintext password. */ string myPass; /** * Global counter to ensure that each Password has a unique ID. */ static int globalPassID; }; #endif // HW5_ADMIN_PASSWORD_H
include/Service.h 0 → 100644 +106 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_SERVICE_H #define HW5_ADMIN_SERVICE_H #include <sstream> #include <string> #include <unordered_set> #include "../include/Device.h" using namespace std; /** * Represents a Service utilizing two or more devices */ class Service { public: // CONSTRUCTORS /** * Creates a Service utilizing between two or more Devices. * @requires d1 != d2 */ template<typename... Rest> Service(Device &d1, Device &d2, Rest &...rest) { serviceID = globalServiceID++; addDevice(d1); addDevice(d2); (addDevice(rest), ...); } /** * A Service cannot be created through the default constructor. */ Service() = delete; /** * Services cannot be copied. */ Service(const Service &otherSvc) = delete; // MODIFIERS /** * Add a Device to this Service. * @param dev The Device to add. */ void addDevice(Device &dev); // INFORMATIONAL /** * @return A collection of all Device s associated with this Service. */ [[nodiscard]] const unordered_set<Device *> &getDevices() const; /** * @param dev The Device to check in this Service. * @return true iff this Service involves the given Device */ bool hasDevice(Device &dev) const; /** * Compares Service objects by their unique ID. * @return true if this Service equals \ref otherSvc */ bool operator==(const Service &otherSvc) const { return serviceID == otherSvc.serviceID; } /** * @return A human-readable version of this Service. */ [[nodiscard]] string toString() const { stringstream strS; strS << "[ service #" << serviceID << " ] "; for (const auto dev : devices) { strS << *dev << " "; } return strS.str(); } /** * Stream access to Service. */ friend std::ostream &operator<<(std::ostream &os, const Service &svc) { os << svc.toString(); return os; } private: /** * A collection of Devices associated with this Service */ unordered_set<Device *> devices; /** * The ID of this Service. */ int serviceID; static int globalServiceID; }; #endif // HW5_ADMIN_SERVICE_H
include/System.h 0 → 100644 +84 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #ifndef HW5_ADMIN_SYSTEM_H #define HW5_ADMIN_SYSTEM_H #include <unordered_set> #include "Service.h" /** * Represents a system of devices and their servicess. */ class System { public: // MODIFIERS /** * Creates a system with an arbitrary number of Devices. * Each Device is provided by reference. */ template<typename... Rest> explicit System(const Rest &...rest) { (addService(rest), ...); } /** * Adds a new Service to the System * @param newSvc The new Service to add. */ void addService(const Service &newSvc); // GETTERS /** * @return All unique Device s associated with this System. */ [[nodiscard]] unordered_set<Device *> getAllDevices() const; /** * @return All unique Service s associated with this System. */ [[nodiscard]] unordered_set<const Service *> getServices() const; // INFORMATIONAL /** * * @return true iff the System is considered secure, meaning that * any two Devices on the same Service have different Passwords. */ [[nodiscard]] bool isSecureQ() const; /** * @return A human-readable version of this System. */ [[nodiscard]] string toString() const { stringstream strS; for (const auto svc : services) { strS << '\t' << *svc << endl; } strS << '\t' << "Is it secure? " << (isSecureQ()?"yes":"no") << endl; strS << '\t' << "# of unique passwords: " << numPasswords() << endl; return strS.str(); } /** * @return The number of unique Passwords associated with the System. */ [[nodiscard]] long numPasswords() const; /** * Stream access to System. */ friend std::ostream &operator<<(std::ostream &os, const System &sys) { os << sys.toString(); return os; } private: /** * Services stored by the system. */ unordered_set<const Service *> services; }; #endif // HW5_ADMIN_SYSTEM_H
main.cpp 0 → 100644 +23 −0 Original line number Diff line number Diff line // // Created by Ari Trachtenberg on 3/17/26. // #include <iostream> #include "include/Service.h" #include "include/Device.h" #include "include/Password.h" #include "include/System.h" int main() { Password p1, p2, p3; Device dev0(p1), dev1(p2), dev2(p3); Service svc0(dev0, dev1); Service svc1(dev0, dev1, dev2); Service svc2(dev0, dev2); System sys(svc0, svc1, svc2); cout << "Initial system:" << endl << sys << endl; dev1.changePassword(p1); cout << "Changed password of dev1:" << endl << sys << endl; }