Commit 564d89eb authored by Ari Trachtenberg's avatar Ari Trachtenberg
Browse files

Initial commit

parent 02f0895d
Loading
Loading
Loading
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;
}