private CorrelationVector(string baseVector, int extension, CorrelationVectorVersion version, bool immutable) { this.BaseVector = baseVector; this.extension = extension; this.Version = version; this.immutable = immutable || CorrelationVector.IsOversized(baseVector, extension, version); }
/// <summary> /// Helper method to run method based on version. /// </summary> /// <param name="correlationVector">String representation of your cV</param> /// <param name="v">Correlation Vector version.</param> /// <param name="functions">The parameters for each cV version. Versions are in order from V1, V2, V3, etc.</param> /// <returns>cV based on cV version.</returns> private static CorrelationVector RunStaticMethod(string correlationVector, CorrelationVectorVersion v, params Func <string, CorrelationVector>[] functions) { if ((int)v < functions.Length) { return(functions[(int)v](correlationVector)); } else { throw new ArgumentException("No function indicated for this version"); } }
private static bool IsOversized(string baseVector, int extension, CorrelationVectorVersion version) { if (!string.IsNullOrEmpty(baseVector)) { int size = baseVector.Length + 1 + (extension > 0 ? (int)Math.Log10(extension) : 0) + 1; return((version == CorrelationVectorVersion.V1 && size > CorrelationVector.MaxVectorLength) || (version == CorrelationVectorVersion.V2 && size > CorrelationVector.MaxVectorLengthV2)); } return(false); }
public static CorrelationVector Spin(string correlationVector, SpinParameters parameters) { CorrelationVectorVersion version = InferVersion(correlationVector); switch (version) { case CorrelationVectorVersion.V1: return(CorrelationVectorV1.Spin(correlationVector, parameters)); case CorrelationVectorVersion.V2: return(CorrelationVectorV2.Spin(correlationVector, parameters)); default: return(null); } }
private static string GetUniqueValue(CorrelationVectorVersion version) { if (CorrelationVectorVersion.V1 == version) { byte[] bytes = Guid.NewGuid().ToByteArray(); return(Convert.ToBase64String(bytes, 0, 12)); } else if (CorrelationVectorVersion.V2 == version) { return(Guid.NewGuid().GetBaseFromGuid()); } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Unsupported correlation vector version: {0}", version)); } }
/// <summary> /// Creates a new correlation vector by applying the Spin operator to an existing value. /// This should be done at the entry point of an operation. /// </summary> /// <param name="correlationVector"> /// Taken from the message header indicated by <see cref="HeaderName"/>. /// </param> /// <param name="parameters"> /// The parameters to use when applying the Spin operator. /// </param> /// <returns>A new correlation vector extended from the current vector.</returns> public static CorrelationVector Spin(string correlationVector, SpinParameters parameters) { if (CorrelationVector.IsImmutable(correlationVector)) { return(CorrelationVector.Parse(correlationVector)); } CorrelationVectorVersion version = CorrelationVector.InferVersion( correlationVector, CorrelationVector.ValidateCorrelationVectorDuringCreation); if (CorrelationVector.ValidateCorrelationVectorDuringCreation) { CorrelationVector.Validate(correlationVector, version); } byte[] entropy = new byte[parameters.EntropyBytes]; rng.NextBytes(entropy); ulong value = (ulong)(DateTime.UtcNow.Ticks >> parameters.TicksBitsToDrop); for (int i = 0; i < parameters.EntropyBytes; i++) { value = (value << 8) | Convert.ToUInt64(entropy[i]); } // Generate a bitmask and mask the lower TotalBits in the value. // The mask is generated by (1 << TotalBits) - 1. We need to handle the edge case // when shifting 64 bits, as it wraps around. value &= (parameters.TotalBits == 64 ? 0 : (ulong)1 << parameters.TotalBits) - 1; string s = unchecked ((uint)value).ToString(); if (parameters.TotalBits > 32) { s = string.Concat((value >> 32).ToString(), ".", s); } string baseVector = string.Concat(correlationVector, ".", s); if (CorrelationVector.IsOversized(baseVector, 0, version)) { return(CorrelationVector.Parse(correlationVector + CorrelationVector.TerminationSign)); } return(new CorrelationVector(baseVector, 0, version, false)); }
private static void Validate(string correlationVector, CorrelationVectorVersion version) { byte maxVectorLength; byte baseLength; if (CorrelationVectorVersion.V1 == version) { maxVectorLength = CorrelationVector.MaxVectorLength; baseLength = CorrelationVector.BaseLength; } else if (CorrelationVectorVersion.V2 == version) { maxVectorLength = CorrelationVector.MaxVectorLengthV2; baseLength = CorrelationVector.BaseLengthV2; } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Unsupported correlation vector version: {0}", version)); } if (string.IsNullOrWhiteSpace(correlationVector) || correlationVector.Length > maxVectorLength) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The {0} correlation vector can not be null or bigger than {1} characters", version, maxVectorLength)); } string[] parts = correlationVector.Split('.'); if (parts.Length < 2 || parts[0].Length != baseLength) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid correlation vector {0}. Invalid base value {1}", correlationVector, parts[0])); } for (int i = 1; i < parts.Length; i++) { int result; if (int.TryParse(parts[i], out result) == false || result < 0) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid correlation vector {0}. Invalid extension value {1}", correlationVector, parts[i])); } } }
/// <summary> /// Creates a new correlation vector by extending an existing value. This should be /// done at the entry point of an operation. /// </summary> /// <param name="correlationVector"> /// Taken from the message header indicated by <see cref="HeaderName"/>. /// </param> /// <returns>A new correlation vector extended from the current vector.</returns> public static CorrelationVector Extend(string correlationVector) { if (CorrelationVector.IsImmutable(correlationVector)) { return(CorrelationVector.Parse(correlationVector)); } CorrelationVectorVersion version = CorrelationVector.InferVersion( correlationVector, CorrelationVector.ValidateCorrelationVectorDuringCreation); if (CorrelationVector.ValidateCorrelationVectorDuringCreation) { CorrelationVector.Validate(correlationVector, version); } if (CorrelationVector.IsOversized(correlationVector, 0, version)) { return(CorrelationVector.Parse(correlationVector + CorrelationVector.TerminationSign)); } return(new CorrelationVector(correlationVector, 0, version, false)); }
/// <summary> /// Converts a string representation of a Correlation Vector into this class. /// </summary> /// <param name="correlationVector">String representation</param> /// <returns>The Correlation Vector based on its version.</returns> public static CorrelationVector Parse(string correlationVector) { CorrelationVectorVersion version = InferVersion(correlationVector); return(RunStaticMethod(correlationVector, version, CorrelationVectorV1.Parse, CorrelationVectorV2.Parse)); }
public static CorrelationVector Extend(string correlationVector) { CorrelationVectorVersion version = InferVersion(correlationVector); return(RunStaticMethod(correlationVector, version, CorrelationVectorV1.Extend, CorrelationVectorV2.Extend)); }
/// <summary> /// Initializes a new instance of the <see cref="CorrelationVector"/> class of the /// given implemenation version. This should only be called when no correlation /// vector was found in the message header. /// </summary> /// <param name="version">The correlation vector implemenation version.</param> public CorrelationVector(CorrelationVectorVersion version) : this(CorrelationVector.GetUniqueValue(version), 0, version, false) { }