# LFSR -Linear Feedback Shift Register
## Links: **[Github Page](http://nikeshbajaj.github.io/Linear_Feedback_Shift_Register/)** | **[Documentation](https://lfsr.readthedocs.io/)** | **[Github](https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register)** | **[PyPi - project](https://pypi.org/project/pylfsr/)** | _ **Installation:** [pip install pylfsr](https://pypi.org/project/pylfsr/)
-----
![CircleCI](https://img.shields.io/circleci/build/github/Nikeshbajaj/Linear_Feedback_Shift_Register)
[![Documentation Status](https://readthedocs.org/projects/lfsr/badge/?version=latest)](https://lfsr.readthedocs.io/en/latest/?badge=latest)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI version fury.io](https://badge.fury.io/py/pylfsr.svg)](https://pypi.org/project/pylfsr/)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pylfsr.svg)](https://pypi.python.org/pypi/pylfsr/)
[![GitHub release](https://img.shields.io/github/release/nikeshbajaj/Linear_Feedback_Shift_Register.svg)](https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/releases)
[![PyPI format](https://img.shields.io/pypi/format/pylfsr.svg)](https://pypi.python.org/pypi/pylfsr/)
[![PyPI implementation](https://img.shields.io/pypi/implementation/pylfsr.svg)](https://pypi.python.org/pypi/pylfsr/)
[![HitCount](http://hits.dwyl.io/nikeshbajaj/pylfsr.svg)](http://hits.dwyl.io/nikeshbajaj/Linear_Feedback_Shift_Register)
![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/Nikeshbajaj/Linear_Feedback_Shift_Register/1.0.1)
![GitHub issues](https://img.shields.io/github/issues-raw/Nikeshbajaj/Linear_Feedback_Shift_Register)
![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/Nikeshbajaj/Linear_Feedback_Shift_Register)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Nikeshbajaj/Linear_Feedback_Shift_Register.svg)](http://isitmaintained.com/project/Nikeshbajaj/Linear_Feedback_Shift_Register "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/Nikeshbajaj/Linear_Feedback_Shift_Register.svg)](http://isitmaintained.com/project/Nikeshbajaj/Linear_Feedback_Shift_Register "Percentage of issues still open")
[![PyPI download month](https://img.shields.io/pypi/dm/pylfsr.svg)](https://pypi.org/project/pylfsr/)
[![PyPI download week](https://img.shields.io/pypi/dw/pylfsr.svg)](https://pypi.org/project/pylfsr/)
[![Hits-of-Code](https://hitsofcode.com/github/Nikeshbajaj/Linear_Feedback_Shift_Register)](https://hitsofcode.com/github/Nikeshbajaj/Linear_Feedback_Shift_Register/view)
[![Generic badge](https://img.shields.io/badge/pip%20install-pylfsr-blue.svg)](https://pypi.org/project/pylfsr/)
[![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](mailto:n.bajaj@qmul.ac.uk)
![PyPI - Downloads](https://img.shields.io/pypi/dm/spkit?style=social)
![CircleCI](https://img.shields.io/circleci/build/github/Nikeshbajaj/Linear_Feedback_Shift_Register?style=social)
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/FibanacciLFSR_2.gif" width="500"/>
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/GaloisLFSR_1.gif" width="500"/>
</p>
[![Generic badge](https://img.shields.io/badge/pip%20install-pylfsr-blue.svg)](https://pypi.org/project/pylfsr/)
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/LFSR.jpg" width="400"/>
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/5bit_8.gif" width="500"/>
</p>
-----
## Table of contents
- [**New Updates**](#new-updates)
- [**Installation**](#installation)
- [**Examples**](#examples)
- [**5-bit LFSR**](#example-1-5-bit-lfsr-with-feedback-polynomial-x5--x2--1)
- [**Vizualize each state**](#example-3--to-visualize-the-process-with-3-bit-lfsr-with-default-counter_start_zero--true)
- [**Plot your LFSR**](#visulizeplot-your-lfsr)
- [**Test properties of LFSR**](#example-6--testing-the-properties)
- [**A5/1 GSM Stream Cipher**](#a51-gsm-stream-cipher-generator)
- [**Geffe Genegerator**](#geffe-generator)
- [**Matlab Implementation**](#matlab)
- [**Cite As**](#cite-as)
-----
## New Updates
## Plot Your LFSR with pylfsr
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/FibanacciLFSR_2.gif" width="600"/>
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/GaloisLFSR_1.gif" width="600"/>
</p>
## Updates:
**Version: 1.0.7:**
- **Added Galois Configuration**
- Improved Documentation
- **Computing LZ complexity**
**Version: 1.0.6:**
- Fixed the bugs (1) missing initial bit (2) exception
- **Added test properties of LFSR**
- **(1) Balance Property**
- **(2) Runlength Property**
- **(3) Autocorrelation Property**
- **Ploting function to display LFSR**
- **A5/1 GSM Stream Ciper Generator**
- **Geffe Generator**
# Installation
## Requirement : *numpy*, *matplotlib*
### with pip
```
pip install pylfsr
```
### Build from the source
Download the repository or clone it with git, after cd in directory build it from source with
```
python setup.py install
```
## Examples
### **Example 1**: 5-bit LFSR with feedback polynomial *x^5 + x^2 + 1*
```
# import LFSR
import numpy as np
from pylfsr import LFSR
L = LFSR()
# print the info
L.info()
5 bit LFSR with feedback polynomial x^5 + x^2 + 1
Expected Period (if polynomial is primitive) = 31
Current :
State : [1 1 1 1 1]
Count : 0
Output bit : -1
feedback bit : -1
```
```
L.next()
L.runKCycle(10)
L.runFullCycle()
L.info()
```
### Example 2**: 5-bit LFSR with custum state and feedback polynomial
```
state = [0,0,0,1,0]
fpoly = [5,4,3,2]
L = LFSR(fpoly=fpoly,initstate =state, verbose=True)
L.info()
tempseq = L.runKCycle(10)
L.set(fpoly=[5,3])
```
### Example 3 ## To visualize the process with 3-bit LFSR, with default counter_start_zero = True
```
state = [1,1,1]
fpoly = [3,2]
L = LFSR(initstate=state,fpoly=fpoly)
print('count \t state \t\toutbit \t seq')
print('-'*50)
for _ in range(15):
print(L.count,L.state,'',L.outbit,L.seq,sep='\t')
L.next()
print('-'*50)
print('Output: ',L.seq)
```
Output :
```
count state outbit seq
--------------------------------------------------
0 [1 1 1] -1 [-1]
1 [0 1 1] 1 [1]
2 [0 0 1] 1 [1 1]
3 [1 0 0] 1 [1 1 1]
4 [0 1 0] 0 [1 1 1 0]
5 [1 0 1] 0 [1 1 1 0 0]
6 [1 1 0] 1 [1 1 1 0 0 1]
7 [1 1 1] 0 [1 1 1 0 0 1 0]
8 [0 1 1] 1 [1 1 1 0 0 1 0 1]
9 [0 0 1] 1 [1 1 1 0 0 1 0 1 1]
10 [1 0 0] 1 [1 1 1 0 0 1 0 1 1 1]
11 [0 1 0] 0 [1 1 1 0 0 1 0 1 1 1 0]
12 [1 0 1] 0 [1 1 1 0 0 1 0 1 1 1 0 0]
13 [1 1 0] 1 [1 1 1 0 0 1 0 1 1 1 0 0 1]
14 [1 1 1] 0 [1 1 1 0 0 1 0 1 1 1 0 0 1 0]
--------------------------------------------------
Output: [1 1 1 0 0 1 0 1 1 1 0 0 1 0 1]
```
### Example 4 ## To visualize the process with 3-bit LFSR, with default counter_start_zero = False
```
state = [1,1,1]
fpoly = [3,2]
L = LFSR(initstate=state,fpoly=fpoly,counter_start_zero=False)
print('count \t state \t\toutbit \t seq')
print('-'*50)
for _ in range(15):
print(L.count,L.state,'',L.outbit,L.seq,sep='\t')
L.next()
print('-'*50)
print('Output: ',L.seq)
```
Output
```
count state outbit seq
--------------------------------------------------
1 [1 1 1] 1 [1]
2 [0 1 1] 1 [1 1]
3 [0 0 1] 1 [1 1 1]
4 [1 0 0] 0 [1 1 1 0]
5 [0 1 0] 0 [1 1 1 0 0]
6 [1 0 1] 1 [1 1 1 0 0 1]
7 [1 1 0] 0 [1 1 1 0 0 1 0]
8 [1 1 1] 1 [1 1 1 0 0 1 0 1]
9 [0 1 1] 1 [1 1 1 0 0 1 0 1 1]
10 [0 0 1] 1 [1 1 1 0 0 1 0 1 1 1]
11 [1 0 0] 0 [1 1 1 0 0 1 0 1 1 1 0]
12 [0 1 0] 0 [1 1 1 0 0 1 0 1 1 1 0 0]
13 [1 0 1] 1 [1 1 1 0 0 1 0 1 1 1 0 0 1]
14 [1 1 0] 0 [1 1 1 0 0 1 0 1 1 1 0 0 1 0]
--------------------------------------------------
Output: [1 1 1 0 0 1 0 1 1 1 0 0 1 0 1]
```
## Visualize & Plot LFSR
```
L.Viz(show=False, show_labels=False,title='R1')
```
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/5bit_0.jpg" width="500"/>
</p>
### Dynamic plot - Animation in notebook
```
%matplotlib notebook
L = LFSR(initstate=[1,0,1,0,1],fpoly=[5,4,3,2],counter_start_zero=False)
fig, ax = plt.subplots(figsize=(8,3))
for _ in range(35):
ax.clear()
L.Viz(ax=ax, title='R1')
plt.ylim([-0.1,None])
#plt.tight_layout()
L.next()
fig.canvas.draw()
plt.pause(0.1)
```
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/5bit_1.gif" width="500"/>
</p>
## Example 5 ## 23 bit LFSR with custum state and feedback polynomial
```
fpoly = [23,19]
L1 = LFSR(fpoly=fpoly,initstate ='ones', verbose=False)
L1.info()
```
Output
```
23 bit LFSR with feedback polynomial x^23 + x^19 + 1
Expected Period (if polynomial is primitive) = 8388607
Current :
State : [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
Count : 0
Output bit : -1
feedback bit : -1
```
```
seq = L1.runKCycle(100)
```
```seq
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1])
```
## Example 6 ## testing the properties
```
state = [1,1,1,1,0]
fpoly = [5,3]
L = LFSR(initstate=state,fpoly=fpoly)
result = L.test_properties(verbose=2)
```
Output
```
1. Periodicity
------------------
- Expected period = 2^M-1 = 31
- Pass?: True
2. Balance Property
-------------------
- Number of 1s = Number of 0s+1 (in a period): (N1s,N0s) = (16, 15)
- Pass?: True
3. Runlength Property
-------------------
- Number of Runs in a period should be of specific order, e.g. [4,2,1,1]
- Runs: [8 4 2 1 1]
- Pass?: True
4. Autocorrelation Property
-------------------
- Autocorrelation of a period should be noise-like, specifically, 1 at k=0, -1/m everywhere else
- Pass?: True
==================
Passed all the tests
==================
```
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/acorr_test.jpg" width="500"/>
</p>
Testing individual property
```
# get a full period sequence
p = L.getFullPeriod()
p
array([0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
0, 1, 0, 0, 1, 0, 1, 1, 0])
```
```
L.balance_property(p.copy())
# (True, (16, 15))
L.runlength_property(p.copy())
# (True, array([8, 4, 2, 1, 1]))
L.autocorr_property(p.copy())[0]
#True
```
## Example 7 ## testing the properties for non-primitive polynomial
```
state = [1,1,1,1,0]
fpoly = [5,1]
L = LFSR(initstate=state,fpoly=fpoly)
result = L.test_properties(verbose=1)
```
Output
```
1. Periodicity
------------------
- Expected period = 2^M-1 = 31
- Pass?: False
2. Balance Property
-------------------
- Number of 1s = Number of 0s+1 (in a period): (N1s,N0s) = (17, 14)
- Pass?: False
3. Runlength Property
-------------------
- Number of Runs in a period should be of specific order, e.g. [4,2,1,1]
- Runs: [10 2 1 1 2]
- Pass?: False
4. Autocorrelation Property
-------------------
- Autocorrelation of a period should be noise-like, specifically, 1 at k=0, -1/m everywhere else
- Pass?: False
==================
Failed one or more tests, check if feedback polynomial is primitive polynomial
==================
```
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/acorr_test_npf.jpg" width="500"/>
</p>
### Example 8**: Get the feedback polynomial or list
Reference : http://www.partow.net/programming/polynomials/index.html
```
L = LFSR()
# list of 5-bit feedback polynomials
fpoly = L.get_fpolyList(m=5)
# list of all feedback polynomials as a dictionary
fpolyDict = L.get_fpolyList()
```
### Changing feedback polynomial in between
```
L.changeFpoly(newfpoly =[23,14],reset=False)
seq1 = L.runKCycle(20)
# Change after 20 clocks
L.changeFpoly(newfpoly =[23,9],reset=False)
seq2 = L.runKCycle(20)
```
# Generators
# A5/1 GSM Stream cipher generator
<p align="center">
<img src="https://upload.wikimedia.org/wikipedia/commons/5/5e/A5-1_GSM_cipher.svg" width="500"/>
</p>
Ref: https://en.wikipedia.org/wiki/A5/1
```
import numpy as np
import matplotlib.pyplot as plt
from pylfsr import A5_1
A5 = A5_1(key='random')
print('key: ',A5.key)
A5.R1.Viz(title='R1')
A5.R2.Viz(title='R2')
A5.R3.Viz(title='R3')
print('key: ',A5.key)
print()
print('count \t cbit\t\tclk\t R1_R2_R3\toutbit \t seq')
print('-'*80)
for _ in range(15):
print(A5.count,A5.getCbits(),A5.clock_bit,A5.getLastbits(),A5.outbit,A5.getSeq(),sep='\t')
A5.next()
print('-'*80)
print('Output: ',A5.seq)
A5.runKCycle(1000)
A5.getSeq()
```
## Enhanced A5/1
Reference Article: **Enhancement of A5/1**: https://doi.org/10.1109/ETNCC.2011.5958486
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/Enhanced_A51.png" width="500"/>
</p>
```
# Three LFSRs initialzed with 'ones' though they are intialized with encription key
R1 = LFSR(fpoly = [19,18,17,14])
R2 = LFSR(fpoly = [23,22,21,8])
R3 = LFSR(fpoly = [22,21])
# clocking bits
b1 = R1.state[8]
b2 = R3.state[10]
b3 = R3.state[10]
```
# Geffe Generator
<p align="center">
<img src="https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/Geffe_0.jpg" width="500"/>
</p>
Ref: Schneier, Bruce. Applied cryptography: protocols, algorithms, and source code in C. john wiley & sons, 2007.
Chaper 16
```
import numpy as np
import matplotlib.pyplot as plt
from pylfsr import Geffe, LFSR
kLFSR = [LFSR(initstate='random') for _ in range(8)] # List of 8 5-bit LFSRs with default feedback polynomial and random initial state
cLFSR = LFSR(initstate='random') # A 5-bit LFSR with for selecting one of 8 output at a time
GG = Geffe(kLFSR_list=kLFSR, cLFSR=cLFSR)
print('key: ',GG.getState())
print()
for _ in range(50):
print(GG.count,GG.m_count,GG.outbit_k,GG.sel_k,GG.outbit,GG.getSeq(),sep='\t')
GG.next()
GG.runKCycle(1000)
GG.getSeq()
```
_______________________________________________________________________________________________
# MATLAB
## For matlab files download it from here
Folder : https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/tree/master/matlabfiles
**Description**
Genrate randon binary sequence using LFSR for any given feedback taps (polynomial),
This will also check Three fundamental Property of LFSR
1. Balance Property
2. Runlength Property
3. Autocorrelation Property
**This MATLAB Code work for any length of LFSR with given taps (feedback polynomial) -Universal, There are three files LFSRv1.m an LFSRv2.m, LFSRv3.m**
### LFSRv1
This function will return all the states of LFSR and will check Three fundamental Property of LFSR
(1) Balance Property (2) Runlength Property (3) Autocorrelation Property
#### EXAMPLE
```
s=[1 1 0 0 1]
t=[5 2]
[seq c] =LFSRv1(s,t)
```
### LFSRv2
This function will return only generated sequence will all the states of LFSR, no verification of properties are done
here. Use this function to avoid verification each time you execute the program.
#### EXAMPLE
```
s=[1 1 0 0 1]
t=[5 2]
[seq c] =LFSRv2(s,t)
```
### LFSRv3 (faster)
*seq = LFSRv3(s,t,N)*
this function generates N bit sequence only. This is faster then other two functions, as this does not gives each state of LFSR
#### EXAMPLE
```
s=[1 1 0 0 1]
t=[5 2]
seq =LFSRv3(s,t,50)
```
## Tips
* If you want to use this function in middle of any program, use LFSRv2 or LFSRv1 with verification =0.
* If you want to make it fast for long length of LFSR,use LFSRv3.m
______________________________________
# Cite As
```
@software{nikesh_bajaj_2021_4726667,
author = {Nikesh Bajaj},
title = {Nikeshbajaj/Linear\_Feedback\_Shift\_Register: 1.0.6},
month = apr,
year = 2021,
publisher = {Zenodo},
version = {1.0.6},
doi = {10.5281/zenodo.4726667},
url = {https://doi.org/10.5281/zenodo.4726667}
}
```
# Contacts:
If any doubt, confusion or feedback please contact me
* **Nikesh Bajaj**
* http://nikeshbajaj.in
* n.bajaj@imperial.ac.uk
* n.bajaj@qmul.ac.uk
* bajaj[dot]nikkey[AT]gmail[dot]?
### PhD Student: Queen Mary University of London & University of Genoa
______________________________________
Raw data
{
"_id": null,
"home_page": "https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register",
"name": "pylfsr",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "lfsr linear-feedback-shift-register random generator gf(2)",
"author": "Nikesh Bajaj",
"author_email": "nikkeshbajaj@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/2a/a9/4a911ede7ca5ada789f46e98ae1b264033f10491542ac64daf82ba9c9188/pylfsr-1.0.7.tar.gz",
"platform": null,
"description": "# LFSR -Linear Feedback Shift Register\r\n\r\n\r\n## Links: **[Github Page](http://nikeshbajaj.github.io/Linear_Feedback_Shift_Register/)** | **[Documentation](https://lfsr.readthedocs.io/)** | **[Github](https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register)** | **[PyPi - project](https://pypi.org/project/pylfsr/)** | _ **Installation:** [pip install pylfsr](https://pypi.org/project/pylfsr/)\r\n-----\r\n\r\n\r\n![CircleCI](https://img.shields.io/circleci/build/github/Nikeshbajaj/Linear_Feedback_Shift_Register)\r\n[![Documentation Status](https://readthedocs.org/projects/lfsr/badge/?version=latest)](https://lfsr.readthedocs.io/en/latest/?badge=latest)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n[![PyPI version fury.io](https://badge.fury.io/py/pylfsr.svg)](https://pypi.org/project/pylfsr/)\r\n[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pylfsr.svg)](https://pypi.python.org/pypi/pylfsr/)\r\n[![GitHub release](https://img.shields.io/github/release/nikeshbajaj/Linear_Feedback_Shift_Register.svg)](https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/releases)\r\n[![PyPI format](https://img.shields.io/pypi/format/pylfsr.svg)](https://pypi.python.org/pypi/pylfsr/)\r\n[![PyPI implementation](https://img.shields.io/pypi/implementation/pylfsr.svg)](https://pypi.python.org/pypi/pylfsr/)\r\n[![HitCount](http://hits.dwyl.io/nikeshbajaj/pylfsr.svg)](http://hits.dwyl.io/nikeshbajaj/Linear_Feedback_Shift_Register)\r\n![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/Nikeshbajaj/Linear_Feedback_Shift_Register/1.0.1)\r\n![GitHub issues](https://img.shields.io/github/issues-raw/Nikeshbajaj/Linear_Feedback_Shift_Register)\r\n![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/Nikeshbajaj/Linear_Feedback_Shift_Register)\r\n[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Nikeshbajaj/Linear_Feedback_Shift_Register.svg)](http://isitmaintained.com/project/Nikeshbajaj/Linear_Feedback_Shift_Register \"Average time to resolve an issue\")\r\n[![Percentage of issues still open](http://isitmaintained.com/badge/open/Nikeshbajaj/Linear_Feedback_Shift_Register.svg)](http://isitmaintained.com/project/Nikeshbajaj/Linear_Feedback_Shift_Register \"Percentage of issues still open\")\r\n\r\n[![PyPI download month](https://img.shields.io/pypi/dm/pylfsr.svg)](https://pypi.org/project/pylfsr/)\r\n[![PyPI download week](https://img.shields.io/pypi/dw/pylfsr.svg)](https://pypi.org/project/pylfsr/)\r\n[![Hits-of-Code](https://hitsofcode.com/github/Nikeshbajaj/Linear_Feedback_Shift_Register)](https://hitsofcode.com/github/Nikeshbajaj/Linear_Feedback_Shift_Register/view)\r\n\r\n[![Generic badge](https://img.shields.io/badge/pip%20install-pylfsr-blue.svg)](https://pypi.org/project/pylfsr/)\r\n[![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](mailto:n.bajaj@qmul.ac.uk)\r\n\r\n![PyPI - Downloads](https://img.shields.io/pypi/dm/spkit?style=social)\r\n![CircleCI](https://img.shields.io/circleci/build/github/Nikeshbajaj/Linear_Feedback_Shift_Register?style=social)\r\n\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/FibanacciLFSR_2.gif\" width=\"500\"/>\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/GaloisLFSR_1.gif\" width=\"500\"/>\r\n</p>\r\n\r\n\r\n\r\n[![Generic badge](https://img.shields.io/badge/pip%20install-pylfsr-blue.svg)](https://pypi.org/project/pylfsr/)\r\n\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/LFSR.jpg\" width=\"400\"/>\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/5bit_8.gif\" width=\"500\"/>\r\n</p>\r\n\r\n\r\n\r\n-----\r\n## Table of contents\r\n- [**New Updates**](#new-updates)\r\n- [**Installation**](#installation)\r\n- [**Examples**](#examples)\r\n - [**5-bit LFSR**](#example-1-5-bit-lfsr-with-feedback-polynomial-x5--x2--1)\r\n - [**Vizualize each state**](#example-3--to-visualize-the-process-with-3-bit-lfsr-with-default-counter_start_zero--true)\r\n - [**Plot your LFSR**](#visulizeplot-your-lfsr)\r\n - [**Test properties of LFSR**](#example-6--testing-the-properties)\r\n- [**A5/1 GSM Stream Cipher**](#a51-gsm-stream-cipher-generator)\r\n- [**Geffe Genegerator**](#geffe-generator)\r\n- [**Matlab Implementation**](#matlab)\r\n- [**Cite As**](#cite-as)\r\n-----\r\n\r\n## New Updates\r\n## Plot Your LFSR with pylfsr\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/FibanacciLFSR_2.gif\" width=\"600\"/>\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/GaloisLFSR_1.gif\" width=\"600\"/>\r\n</p>\r\n\r\n## Updates:\r\n **Version: 1.0.7:**\r\n - **Added Galois Configuration**\r\n - Improved Documentation\r\n - **Computing LZ complexity**\r\n\r\n **Version: 1.0.6:**\r\n - Fixed the bugs (1) missing initial bit (2) exception\r\n - **Added test properties of LFSR**\r\n\t - **(1) Balance Property**\r\n\t - **(2) Runlength Property**\r\n\t - **(3) Autocorrelation Property**\r\n - **Ploting function to display LFSR**\r\n - **A5/1 GSM Stream Ciper Generator**\r\n - **Geffe Generator**\r\n\r\n\r\n# Installation\r\n\r\n## Requirement : *numpy*, *matplotlib*\r\n\r\n### with pip\r\n\r\n```\r\npip install pylfsr\r\n```\r\n\r\n\r\n### Build from the source\r\nDownload the repository or clone it with git, after cd in directory build it from source with\r\n\r\n```\r\npython setup.py install\r\n```\r\n\r\n## Examples\r\n### **Example 1**: 5-bit LFSR with feedback polynomial *x^5 + x^2 + 1*\r\n\r\n```\r\n# import LFSR\r\nimport numpy as np\r\nfrom pylfsr import LFSR\r\n\r\nL = LFSR()\r\n\r\n# print the info\r\nL.info()\r\n\r\n5 bit LFSR with feedback polynomial x^5 + x^2 + 1\r\nExpected Period (if polynomial is primitive) = 31\r\nCurrent :\r\nState : [1 1 1 1 1]\r\nCount : 0\r\nOutput bit : -1\r\nfeedback bit : -1\r\n```\r\n\r\n\r\n```\r\nL.next()\r\nL.runKCycle(10)\r\nL.runFullCycle()\r\nL.info()\r\n```\r\n\r\n### Example 2**: 5-bit LFSR with custum state and feedback polynomial\r\n\r\n```\r\nstate = [0,0,0,1,0]\r\nfpoly = [5,4,3,2]\r\nL = LFSR(fpoly=fpoly,initstate =state, verbose=True)\r\nL.info()\r\ntempseq = L.runKCycle(10)\r\nL.set(fpoly=[5,3])\r\n```\r\n\r\n### Example 3 ## To visualize the process with 3-bit LFSR, with default counter_start_zero = True\r\n```\r\nstate = [1,1,1]\r\nfpoly = [3,2]\r\nL = LFSR(initstate=state,fpoly=fpoly)\r\nprint('count \\t state \\t\\toutbit \\t seq')\r\nprint('-'*50)\r\nfor _ in range(15):\r\n print(L.count,L.state,'',L.outbit,L.seq,sep='\\t')\r\n L.next()\r\nprint('-'*50)\r\nprint('Output: ',L.seq)\r\n```\r\nOutput :\r\n\r\n```\r\ncount \t state \t\toutbit \t seq\r\n--------------------------------------------------\r\n0\t\t[1 1 1]\t\t-1\t[-1]\r\n1\t\t[0 1 1]\t\t1\t[1]\r\n2\t\t[0 0 1]\t\t1\t[1 1]\r\n3\t\t[1 0 0]\t\t1\t[1 1 1]\r\n4\t\t[0 1 0]\t\t0\t[1 1 1 0]\r\n5\t\t[1 0 1]\t\t0\t[1 1 1 0 0]\r\n6\t\t[1 1 0]\t\t1\t[1 1 1 0 0 1]\r\n7\t\t[1 1 1]\t\t0\t[1 1 1 0 0 1 0]\r\n8\t\t[0 1 1]\t\t1\t[1 1 1 0 0 1 0 1]\r\n9\t\t[0 0 1]\t\t1\t[1 1 1 0 0 1 0 1 1]\r\n10\t\t[1 0 0]\t\t1\t[1 1 1 0 0 1 0 1 1 1]\r\n11\t\t[0 1 0]\t\t0\t[1 1 1 0 0 1 0 1 1 1 0]\r\n12\t\t[1 0 1]\t\t0\t[1 1 1 0 0 1 0 1 1 1 0 0]\r\n13\t\t[1 1 0]\t\t1\t[1 1 1 0 0 1 0 1 1 1 0 0 1]\r\n14\t\t[1 1 1]\t\t0\t[1 1 1 0 0 1 0 1 1 1 0 0 1 0]\r\n--------------------------------------------------\r\nOutput: [1 1 1 0 0 1 0 1 1 1 0 0 1 0 1]\r\n```\r\n\r\n### Example 4 ## To visualize the process with 3-bit LFSR, with default counter_start_zero = False\r\n```\r\nstate = [1,1,1]\r\nfpoly = [3,2]\r\nL = LFSR(initstate=state,fpoly=fpoly,counter_start_zero=False)\r\nprint('count \\t state \\t\\toutbit \\t seq')\r\nprint('-'*50)\r\nfor _ in range(15):\r\n print(L.count,L.state,'',L.outbit,L.seq,sep='\\t')\r\n L.next()\r\nprint('-'*50)\r\nprint('Output: ',L.seq)\r\n```\r\n\r\nOutput\r\n```\r\ncount \t state \t\toutbit \t seq\r\n--------------------------------------------------\r\n1\t[1 1 1]\t\t1\t[1]\r\n2\t[0 1 1]\t\t1\t[1 1]\r\n3\t[0 0 1]\t\t1\t[1 1 1]\r\n4\t[1 0 0]\t\t0\t[1 1 1 0]\r\n5\t[0 1 0]\t\t0\t[1 1 1 0 0]\r\n6\t[1 0 1]\t\t1\t[1 1 1 0 0 1]\r\n7\t[1 1 0]\t\t0\t[1 1 1 0 0 1 0]\r\n8\t[1 1 1]\t\t1\t[1 1 1 0 0 1 0 1]\r\n9\t[0 1 1]\t\t1\t[1 1 1 0 0 1 0 1 1]\r\n10\t[0 0 1]\t\t1\t[1 1 1 0 0 1 0 1 1 1]\r\n11\t[1 0 0]\t\t0\t[1 1 1 0 0 1 0 1 1 1 0]\r\n12\t[0 1 0]\t\t0\t[1 1 1 0 0 1 0 1 1 1 0 0]\r\n13\t[1 0 1]\t\t1\t[1 1 1 0 0 1 0 1 1 1 0 0 1]\r\n14\t[1 1 0]\t\t0\t[1 1 1 0 0 1 0 1 1 1 0 0 1 0]\r\n--------------------------------------------------\r\nOutput: [1 1 1 0 0 1 0 1 1 1 0 0 1 0 1]\r\n```\r\n\r\n## Visualize & Plot LFSR\r\n```\r\nL.Viz(show=False, show_labels=False,title='R1')\r\n\r\n```\r\n\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/5bit_0.jpg\" width=\"500\"/>\r\n</p>\r\n\r\n### Dynamic plot - Animation in notebook\r\n```\r\n%matplotlib notebook\r\nL = LFSR(initstate=[1,0,1,0,1],fpoly=[5,4,3,2],counter_start_zero=False)\r\nfig, ax = plt.subplots(figsize=(8,3))\r\nfor _ in range(35):\r\n ax.clear()\r\n L.Viz(ax=ax, title='R1')\r\n plt.ylim([-0.1,None])\r\n #plt.tight_layout()\r\n L.next()\r\n fig.canvas.draw()\r\n plt.pause(0.1)\r\n\r\n```\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/5bit_1.gif\" width=\"500\"/>\r\n</p>\r\n\r\n\r\n## Example 5 ## 23 bit LFSR with custum state and feedback polynomial\r\n```\r\nfpoly = [23,19]\r\nL1 = LFSR(fpoly=fpoly,initstate ='ones', verbose=False)\r\nL1.info()\r\n```\r\nOutput\r\n```\r\n23 bit LFSR with feedback polynomial x^23 + x^19 + 1\r\nExpected Period (if polynomial is primitive) = 8388607\r\nCurrent :\r\n State : [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]\r\n Count : 0\r\n Output bit : -1\r\n feedback bit : -1\r\n```\r\n```\r\nseq = L1.runKCycle(100)\r\n```\r\n\r\n```seq\r\narray([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r\n1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\r\n1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\r\n1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,\r\n1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1])\r\n```\r\n## Example 6 ## testing the properties\r\n```\r\nstate = [1,1,1,1,0]\r\nfpoly = [5,3]\r\nL = LFSR(initstate=state,fpoly=fpoly)\r\nresult = L.test_properties(verbose=2)\r\n```\r\nOutput\r\n```\r\n1. Periodicity\r\n------------------\r\n - Expected period = 2^M-1 = 31\r\n - Pass?: True\r\n\r\n2. Balance Property\r\n-------------------\r\n - Number of 1s = Number of 0s+1 (in a period): (N1s,N0s) = (16, 15)\r\n - Pass?: True\r\n\r\n3. Runlength Property\r\n-------------------\r\n - Number of Runs in a period should be of specific order, e.g. [4,2,1,1]\r\n - Runs: [8 4 2 1 1]\r\n - Pass?: True\r\n\r\n4. Autocorrelation Property\r\n-------------------\r\n - Autocorrelation of a period should be noise-like, specifically, 1 at k=0, -1/m everywhere else\r\n - Pass?: True\r\n\r\n==================\r\nPassed all the tests\r\n==================\r\n```\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/acorr_test.jpg\" width=\"500\"/>\r\n</p>\r\n\r\nTesting individual property\r\n```\r\n# get a full period sequence\r\np = L.getFullPeriod()\r\np\r\narray([0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,\r\n 0, 1, 0, 0, 1, 0, 1, 1, 0])\r\n```\r\n\r\n```\r\nL.balance_property(p.copy())\r\n# (True, (16, 15))\r\n\r\nL.runlength_property(p.copy())\r\n# (True, array([8, 4, 2, 1, 1]))\r\n\r\nL.autocorr_property(p.copy())[0]\r\n#True\r\n```\r\n\r\n## Example 7 ## testing the properties for non-primitive polynomial\r\n```\r\nstate = [1,1,1,1,0]\r\nfpoly = [5,1]\r\nL = LFSR(initstate=state,fpoly=fpoly)\r\nresult = L.test_properties(verbose=1)\r\n```\r\nOutput\r\n```\r\n1. Periodicity\r\n------------------\r\n - Expected period = 2^M-1 = 31\r\n - Pass?: False\r\n\r\n2. Balance Property\r\n-------------------\r\n - Number of 1s = Number of 0s+1 (in a period): (N1s,N0s) = (17, 14)\r\n - Pass?: False\r\n\r\n3. Runlength Property\r\n-------------------\r\n - Number of Runs in a period should be of specific order, e.g. [4,2,1,1]\r\n - Runs: [10 2 1 1 2]\r\n - Pass?: False\r\n\r\n4. Autocorrelation Property\r\n-------------------\r\n - Autocorrelation of a period should be noise-like, specifically, 1 at k=0, -1/m everywhere else\r\n - Pass?: False\r\n\r\n==================\r\nFailed one or more tests, check if feedback polynomial is primitive polynomial\r\n==================\r\n```\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/acorr_test_npf.jpg\" width=\"500\"/>\r\n</p>\r\n\r\n\r\n### Example 8**: Get the feedback polynomial or list\r\nReference : http://www.partow.net/programming/polynomials/index.html\r\n\r\n```\r\nL = LFSR()\r\n# list of 5-bit feedback polynomials\r\nfpoly = L.get_fpolyList(m=5)\r\n\r\n# list of all feedback polynomials as a dictionary\r\nfpolyDict = L.get_fpolyList()\r\n```\r\n\r\n\r\n### Changing feedback polynomial in between\r\n```\r\nL.changeFpoly(newfpoly =[23,14],reset=False)\r\nseq1 = L.runKCycle(20)\r\n\r\n# Change after 20 clocks\r\nL.changeFpoly(newfpoly =[23,9],reset=False)\r\nseq2 = L.runKCycle(20)\r\n```\r\n\r\n# Generators\r\n# A5/1 GSM Stream cipher generator\r\n<p align=\"center\">\r\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/5/5e/A5-1_GSM_cipher.svg\" width=\"500\"/>\r\n</p>\r\n\r\nRef: https://en.wikipedia.org/wiki/A5/1\r\n\r\n```\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\nfrom pylfsr import A5_1\r\n\r\nA5 = A5_1(key='random')\r\nprint('key: ',A5.key)\r\nA5.R1.Viz(title='R1')\r\nA5.R2.Viz(title='R2')\r\nA5.R3.Viz(title='R3')\r\n\r\nprint('key: ',A5.key)\r\nprint()\r\nprint('count \\t cbit\\t\\tclk\\t R1_R2_R3\\toutbit \\t seq')\r\nprint('-'*80)\r\nfor _ in range(15):\r\n print(A5.count,A5.getCbits(),A5.clock_bit,A5.getLastbits(),A5.outbit,A5.getSeq(),sep='\\t')\r\n A5.next()\r\nprint('-'*80)\r\nprint('Output: ',A5.seq)\r\n\r\nA5.runKCycle(1000)\r\nA5.getSeq()\r\n\r\n```\r\n\r\n\r\n## Enhanced A5/1\r\n\r\nReference Article: **Enhancement of A5/1**: https://doi.org/10.1109/ETNCC.2011.5958486\r\n\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/Enhanced_A51.png\" width=\"500\"/>\r\n</p>\r\n\r\n\r\n```\r\n# Three LFSRs initialzed with 'ones' though they are intialized with encription key\r\nR1 = LFSR(fpoly = [19,18,17,14])\r\nR2 = LFSR(fpoly = [23,22,21,8])\r\nR3 = LFSR(fpoly = [22,21])\r\n\r\n# clocking bits\r\nb1 = R1.state[8]\r\nb2 = R3.state[10]\r\nb3 = R3.state[10]\r\n\r\n```\r\n\r\n\r\n# Geffe Generator\r\n<p align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/nikeshbajaj/Linear_Feedback_Shift_Register/master/images/Geffe_0.jpg\" width=\"500\"/>\r\n</p>\r\n\r\nRef: Schneier, Bruce. Applied cryptography: protocols, algorithms, and source code in C. john wiley & sons, 2007.\r\n\tChaper 16\r\n\r\n```\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\nfrom pylfsr import Geffe, LFSR\r\n\r\nkLFSR = [LFSR(initstate='random') for _ in range(8)] # List of 8 5-bit LFSRs with default feedback polynomial and random initial state\r\ncLFSR = LFSR(initstate='random') # A 5-bit LFSR with for selecting one of 8 output at a time\r\n\r\nGG = Geffe(kLFSR_list=kLFSR, cLFSR=cLFSR)\r\n\r\nprint('key: ',GG.getState())\r\nprint()\r\nfor _ in range(50):\r\n print(GG.count,GG.m_count,GG.outbit_k,GG.sel_k,GG.outbit,GG.getSeq(),sep='\\t')\r\n GG.next()\r\n\r\nGG.runKCycle(1000)\r\nGG.getSeq()\r\n```\r\n\r\n_______________________________________________________________________________________________\r\n\r\n# MATLAB\r\n## For matlab files download it from here\r\nFolder : https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/tree/master/matlabfiles\r\n\r\n**Description**\r\nGenrate randon binary sequence using LFSR for any given feedback taps (polynomial),\r\nThis will also check Three fundamental Property of LFSR\r\n1. Balance Property\r\n2. Runlength Property\r\n3. Autocorrelation Property\r\n\r\n**This MATLAB Code work for any length of LFSR with given taps (feedback polynomial) -Universal, There are three files LFSRv1.m an LFSRv2.m, LFSRv3.m**\r\n\r\n### LFSRv1\r\nThis function will return all the states of LFSR and will check Three fundamental Property of LFSR\r\n(1) Balance Property (2) Runlength Property (3) Autocorrelation Property\r\n\r\n#### EXAMPLE\r\n```\r\ns=[1 1 0 0 1]\r\nt=[5 2]\r\n[seq c] =LFSRv1(s,t)\r\n```\r\n\r\n### LFSRv2\r\nThis function will return only generated sequence will all the states of LFSR, no verification of properties are done\r\nhere. Use this function to avoid verification each time you execute the program.\r\n#### EXAMPLE\r\n```\r\ns=[1 1 0 0 1]\r\nt=[5 2]\r\n[seq c] =LFSRv2(s,t)\r\n```\r\n\r\n### LFSRv3 (faster)\r\n*seq = LFSRv3(s,t,N)*\r\nthis function generates N bit sequence only. This is faster then other two functions, as this does not gives each state of LFSR\r\n\r\n#### EXAMPLE\r\n```\r\ns=[1 1 0 0 1] \r\nt=[5 2]\r\nseq =LFSRv3(s,t,50)\r\n```\r\n\r\n\r\n\r\n## Tips\r\n* If you want to use this function in middle of any program, use LFSRv2 or LFSRv1 with verification =0.\r\n* If you want to make it fast for long length of LFSR,use LFSRv3.m\r\n\r\n______________________________________\r\n\r\n# Cite As\r\n```\r\n@software{nikesh_bajaj_2021_4726667,\r\n author = {Nikesh Bajaj},\r\n title = {Nikeshbajaj/Linear\\_Feedback\\_Shift\\_Register: 1.0.6},\r\n month = apr,\r\n year = 2021,\r\n publisher = {Zenodo},\r\n version = {1.0.6},\r\n doi = {10.5281/zenodo.4726667},\r\n url = {https://doi.org/10.5281/zenodo.4726667}\r\n}\r\n```\r\n\r\n\r\n# Contacts:\r\n\r\nIf any doubt, confusion or feedback please contact me\r\n* **Nikesh Bajaj**\r\n* http://nikeshbajaj.in\r\n* n.bajaj@imperial.ac.uk\r\n* n.bajaj@qmul.ac.uk\r\n* bajaj[dot]nikkey[AT]gmail[dot]?\r\n### PhD Student: Queen Mary University of London & University of Genoa\r\n______________________________________\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Linear Feedback Shift Register",
"version": "1.0.7",
"split_keywords": [
"lfsr",
"linear-feedback-shift-register",
"random",
"generator",
"gf(2)"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2fea12ed0f9ce0037d67714214aa86bdc4da1e5a378741d51c0af15e6f139995",
"md5": "1c6c1d895c67bea85a9bdad92bc50622",
"sha256": "07ac5b64222bbe123d268255863bac68c5a1a76a52837087c3c5353a6fe2bc6d"
},
"downloads": -1,
"filename": "pylfsr-1.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1c6c1d895c67bea85a9bdad92bc50622",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 28034,
"upload_time": "2023-01-03T12:40:08",
"upload_time_iso_8601": "2023-01-03T12:40:08.373678Z",
"url": "https://files.pythonhosted.org/packages/2f/ea/12ed0f9ce0037d67714214aa86bdc4da1e5a378741d51c0af15e6f139995/pylfsr-1.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2aa94a911ede7ca5ada789f46e98ae1b264033f10491542ac64daf82ba9c9188",
"md5": "18087b1702966a20c575830251cbe7a9",
"sha256": "1f14f10a56bbff7235b6a028eaa10ebcfc3903b240da78a129cde2042c259882"
},
"downloads": -1,
"filename": "pylfsr-1.0.7.tar.gz",
"has_sig": false,
"md5_digest": "18087b1702966a20c575830251cbe7a9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 32114,
"upload_time": "2023-01-03T12:40:10",
"upload_time_iso_8601": "2023-01-03T12:40:10.207422Z",
"url": "https://files.pythonhosted.org/packages/2a/a9/4a911ede7ca5ada789f46e98ae1b264033f10491542ac64daf82ba9c9188/pylfsr-1.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-01-03 12:40:10",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "Nikeshbajaj",
"github_project": "Linear_Feedback_Shift_Register",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"circle": true,
"requirements": [],
"lcname": "pylfsr"
}