Showing results for 
Search instead for 
Did you mean: 

CUCM SIP Lua Script to Randomize Caller ID or ANI Numbers

Jawad Al Akrabawi
Cisco Employee
Cisco Employee

Consider a case where you have a PRI range of 200 DID numbers allocated by the Service Provider, and for some reason, you want all your outgoing calls to randomly select one of the 200 DID numbers, for example you are conducting a survey and you don't want everyone to call you back on the main number and overload the operator.

There is no native way to do this on CUCM, but you can configure a Lua SIP Normalization script to achieve this to some extent assuming your voice gateway or the other side of the call is running SIP.

Disclaimer: Custom Normalization scripts may not supported by Cisco TAC, and you need fair amount of knowledge in both Lua language programming skills and SIP messaging stack. Use with caution. There is no warranty or guarantee.


  • The service provider expects you to send caller ID with an imaginary format of 0222222XXX, where the last 3 digits could be in the range of 000-199
  • The voice gateway is running SIP, and we assume that you already have a SIP trunk configured towards the voice gateway.
  • While you can configure the voice gateway with dial peers and translations rules to achieve the same result, the range of DID could be so large, and you don't want to end up writing hundreds of dial peers to match each destination.


Go to Device>Device Settings>SIP Normalization Script.



Create new script and paste a Lua code:



The code we used in this example is:

M = {}
function M.outbound_INVITE(msg)
This part is only a create a simple code to generate a random number, we are
reading the Date header from the invite msg and extracting hours, minutes and seconds
to create a seed value using "minutes".
This is partially a simple Linear congruential generator since the Lua library
in current CUCM application is restrictied and do not contain any Math Library.
The code will generate random number between 0 and 199 based on an initial seed
matching the "minute"
local datenow = msg:getHeader("Date")
local _, _,hour,minute,sec= string.find(datenow, "(%d+):(%d+):(%d+)")
local N1=101
local N2=101
local I=1
local randomANI={}
for I=1,60 do
randomANI[I+1]=(N1 * randomANI[I] + N2 ) % (200)
-- Here after generating a series of 60 random numbers, we will pick one value
-- randomly using the sec to somehow make our numbers selection more random.
local ANI= string.format("%003d",tostring(randomANI[sec+1]))
--[[ Here we apply Number mask to different headers in the outgoing invite msg.
-- These are the most common headers carrying the Caller ID, but other headers
-- might be used service providers to parse the Caller ID, so you might need
to edit more headers.
msg:applyNumberMask("From", "0222222"..ANI)
local remotepartyid = msg:getHeader("Remote-Party-ID")
if remotepartyid then
msg:applyNumberMask("Remote-Party-ID", "0222222"..ANI)
local passertedidentity = msg:getHeader("P-Asserted-Identity")
if passertedidentity then
msg:applyNumberMask("P-Asserted-Identity", "0222222"..ANI)
return M


The above script applies a number mask to the call, similar to situation where you configured a number mask for phone, except here that we are using the script to randomize the applied number mask of some SIP headers.

Assign the script to the SIP Trunk and reset the Trunk.



Conduct some tests and verify that the headers have changed.


When conducting tests,  each call was presented with a different calling number, I haven't had the chance to test this with a real voice gateway, as I was using a basic standalone SIP phone on the other side of the CUCM SIP Trunk, but from the traces, it is clear that the following headers indeed changed randomly for each call:

  • From Header
  • Remote-Party-ID Header
  • P-Asserted-Identity


Notice that there are many other fields or headers that might carry the caller ID. Service providers normally use the above mentioned ones to extract it, however, some service providers might use other fields to parse the caller ID depending on some certain conditions.

The challenging part of the code is to get a pseudo code random number generator. The current library application of Lua in SIP normalization for CUCM is very restricted to mostly dealing with strings and texts, and only basic math is available. If the Lua math library was available, we could have generated the random number in a pair of code lines.

Like any pseudo random generator, we need to include a seed value in the algorithm, and for that, we extracted the current minutes of time from the SIP invite message itself. We then created a simple sort of Linear congruential generator (LCG). This is pure mathematics and statistics, and you need to select the variables N1, N2 and even the Modulus so that you have almost complete cycle of random numbers. The seed value itself changes every minute, and the code will generate a sequence of 60 random numbers, and then depending on the current “second” extracted from invite message, the code will select a value. This is somehow to guarantee that selected numbers are random, and that at least each second, a new number is selected.

You can be creative provided you have development skills, for example, you can add conditions to outgoing calls to check certain parameters before randomizing the Caller ID, such as original caller number, or even a prefix for the destination, not to mention passing parameters from the CUCM SIP Trunk page itself, this is completely outside the scope of my basic programming skills.




2 Replies 2

Roger Kallberg
VIP Expert VIP Expert
VIP Expert

Nice post. It would be recommended if you put this into a knowledge article instead of in a post that is intended for questions.

Response Signature

Interesting article, I really like the idea!

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community:

Recognize Your Peers