コード例 #1
0
 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);
 }
コード例 #2
0
 /// <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");
     }
 }
コード例 #3
0
 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);
 }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
 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));
     }
 }
コード例 #6
0
        /// <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));
        }
コード例 #7
0
        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]));
                }
            }
        }
コード例 #8
0
        /// <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));
        }
コード例 #9
0
        /// <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));
        }
コード例 #10
0
        public static CorrelationVector Extend(string correlationVector)
        {
            CorrelationVectorVersion version = InferVersion(correlationVector);

            return(RunStaticMethod(correlationVector, version, CorrelationVectorV1.Extend, CorrelationVectorV2.Extend));
        }
コード例 #11
0
 /// <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)
 {
 }