Last active
May 8, 2017 22:00
-
-
Save tuxuser/ff4464394be2aa92fdabab1a7c02f6bb to your computer and use it in GitHub Desktop.
MS Correlation Vector (MS-CV)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Microsoft Correlation Vector, used for telemetry purposes by Microsoft Web APIs | |
Source: https://github.com/Microsoft/Telemetry-Client-for-Android/blob/master/AndroidCll/src/main/java/com/microsoft/cll/android/CorrelationVector.java | |
''' | |
import re | |
import math | |
import random | |
class MsCorrelationVector(object): | |
MAX_CORRELATION_VECTOR_LENGTH = 20 | |
CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | |
ID0_LENGTH = 16 | |
INT_MAX_VALUE = 2147483647 | |
def __init__(self): | |
self.base_vector = self.seed_correlation_vector() | |
self.current_vector = 1 | |
def can_extend(self): | |
vector_size = math.floor(math.log10(self.current_vector) + 1) | |
if len(self.base_vector) + 1 + vector_size + 1 + 1 > self.MAX_CORRELATION_VECTOR_LENGTH: | |
return False | |
else: | |
return True | |
def can_increment(self, new_vector): | |
if new_vector - 1 == self.INT_MAX_VALUE: | |
return False | |
vector_size = math.floor(math.log10(new_vector) + 1) | |
if len(self.base_vector) + vector_size + 1 > self.MAX_CORRELATION_VECTOR_LENGTH: | |
return False | |
else: | |
return True | |
def extend(self): | |
if self.can_extend(): | |
self.base_vector = self.get_value() | |
self.current_vector = 1 | |
return self.get_value() | |
def get_value(self): | |
return '%s.%s' % (self.base_vector, self.current_vector) | |
def increment(self): | |
new_vector = self.current_vector + 1 | |
if self.can_increment(new_vector): | |
self.current_vector = new_vector | |
return self.get_value() | |
def is_valid(self, vector): | |
if len(vector) > self.MAX_CORRELATION_VECTOR_LENGTH: | |
return False | |
validation_pattern = re.compile('^[' + self.CHARSET + ']{16}(.[0-9]+)+$') | |
if not validation_pattern.match(vector): | |
return False | |
else: | |
return True | |
def seed_correlation_vector(self): | |
return ''.join([random.choice(self.CHARSET) for i in range(self.ID0_LENGTH)]) | |
def set_value(self, vector): | |
if self.is_valid(vector): | |
base, current = vector.split('.') | |
self.base_vector = base | |
self.current_vector = int(current) | |
else: | |
raise Exception('Cannot set invalid correlation vector value') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment